<?php

namespace Tests\Feature;

use App\Filament\Resources\GiftVoucherResource\Pages\ListGiftVouchers;
use App\Filament\Resources\MediaStorageTargetResource\Pages\EditMediaStorageTarget;
use App\Filament\Resources\TaskResource\Pages\ImportTasks;
use App\Models\Emotion;
use App\Models\EventType;
use App\Models\GiftVoucher;
use App\Models\MediaStorageTarget;
use App\Models\SuperAdminActionLog;
use App\Models\Task;
use App\Models\User;
use App\Services\GiftVouchers\GiftVoucherService;
use Filament\Actions\Testing\TestAction;
use Filament\Facades\Filament;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Storage;
use Livewire\Livewire;
use Tests\TestCase;

class SuperAdminAuditLogMutationTest extends TestCase
{
    use RefreshDatabase;

    public function test_save_without_changes_does_not_create_audit_log(): void
    {
        $user = User::factory()->create(['role' => 'super_admin']);
        $target = MediaStorageTarget::query()->create([
            'key' => 'hot-storage',
            'name' => 'Hot Storage',
            'driver' => 'local',
            'config' => [],
            'is_hot' => true,
            'is_default' => false,
            'is_active' => true,
            'priority' => 0,
        ]);

        $this->bootSuperAdminPanel($user);

        Livewire::test(EditMediaStorageTarget::class, ['record' => $target->getKey()])
            ->call('save');

        $this->assertFalse(SuperAdminActionLog::query()->exists());
    }

    public function test_gift_voucher_issue_action_creates_audit_log(): void
    {
        $user = User::factory()->create(['role' => 'super_admin']);
        $voucher = GiftVoucher::factory()->create();

        $this->bootSuperAdminPanel($user);

        $this->mock(GiftVoucherService::class, function ($mock) use ($voucher): void {
            $mock->shouldReceive('issueFromPaddle')
                ->once()
                ->andReturn($voucher);
        });

        Livewire::test(ListGiftVouchers::class)
            ->callAction(TestAction::make('issue'), [
                'amount' => 25,
                'currency' => 'EUR',
                'purchaser_email' => 'buyer@example.com',
            ]);

        $this->assertTrue(SuperAdminActionLog::query()
            ->where('action', 'gift-voucher.issued')
            ->where('subject_id', $voucher->id)
            ->exists());
    }

    public function test_task_import_creates_audit_logs(): void
    {
        Storage::fake('public');

        $user = User::factory()->create(['role' => 'super_admin']);
        $emotion = Emotion::factory()->create(['name' => ['de' => 'Freude', 'en' => 'Joy']]);
        $eventType = EventType::factory()->create(['slug' => 'party']);

        $headers = [
            'emotion_name',
            'emotion_name_de',
            'emotion_name_en',
            'event_type_slug',
            'title_de',
            'title_en',
            'description_de',
            'description_en',
            'difficulty',
            'example_text_de',
            'example_text_en',
            'sort_order',
            'is_active',
        ];
        $row = [
            '',
            $emotion->name['de'],
            $emotion->name['en'],
            $eventType->slug,
            'Aufgabe',
            'Task',
            'Beschreibung',
            'Description',
            'easy',
            'Beispiel',
            'Example',
            '1',
            '1',
        ];

        $csv = implode(',', $headers)."\n".implode(',', $row)."\n";

        Storage::disk('public')->put('imports/tasks.csv', $csv);

        $this->bootSuperAdminPanel($user);

        $component = app(ImportTasks::class);
        $method = new \ReflectionMethod($component, 'importTasksCsv');
        $method->setAccessible(true);
        $method->invoke($component, Storage::disk('public')->path('imports/tasks.csv'));

        $this->assertSame(1, Task::query()->count());
        $this->assertTrue(SuperAdminActionLog::query()
            ->where('action', 'task.created')
            ->exists());
    }

    private function bootSuperAdminPanel(User $user): void
    {
        $panel = Filament::getPanel('superadmin');

        $this->assertNotNull($panel);

        Filament::setCurrentPanel($panel);
        Filament::bootCurrentPanel();
        Filament::auth()->login($user);
    }
}
