<?php

declare(strict_types=1);

use App\Jobs\BackfillFindingLifecycleJob;
use App\Models\Finding;
use App\Models\Tenant;
use App\Services\OperationRunService;
use App\Services\Runbooks\FindingsLifecycleBackfillRunbookService;
use App\Services\Runbooks\FindingsLifecycleBackfillScope;
use Filament\Facades\Filament;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Queue;
use Illuminate\Validation\ValidationException;

uses(RefreshDatabase::class);

beforeEach(function () {
    Filament::setCurrentPanel('system');
    Filament::bootCurrentPanel();

    Tenant::factory()->create([
        'tenant_id' => null,
        'external_id' => 'platform',
        'name' => 'Platform',
    ]);
});

it('is idempotent: after a successful run, preflight reports nothing to do', function () {
    Queue::fake();

    $platformTenant = Tenant::query()->where('external_id', 'platform')->firstOrFail();

    $tenant = Tenant::factory()->create([
        'workspace_id' => (int) $platformTenant->workspace_id,
    ]);

    Finding::factory()->create([
        'tenant_id' => (int) $tenant->getKey(),
        'due_at' => null,
    ]);

    $runbook = app(FindingsLifecycleBackfillRunbookService::class);

    $initial = $runbook->preflight(FindingsLifecycleBackfillScope::singleTenant((int) $tenant->getKey()));

    expect($initial['affected_count'])->toBe(1);

    $runbook->start(
        scope: FindingsLifecycleBackfillScope::singleTenant((int) $tenant->getKey()),
        initiator: null,
        reason: null,
        source: 'system_ui',
    );

    $job = new BackfillFindingLifecycleJob(
        tenantId: (int) $tenant->getKey(),
        workspaceId: (int) $tenant->workspace_id,
        initiatorUserId: null,
    );

    $job->handle(
        app(OperationRunService::class),
        app(\App\Services\Findings\FindingSlaPolicy::class),
        $runbook,
    );

    $after = $runbook->preflight(FindingsLifecycleBackfillScope::singleTenant((int) $tenant->getKey()));

    expect($after['affected_count'])->toBe(0);

    expect(fn () => $runbook->start(
        scope: FindingsLifecycleBackfillScope::singleTenant((int) $tenant->getKey()),
        initiator: null,
        reason: null,
        source: 'system_ui',
    ))->toThrow(ValidationException::class);
});
