<?php

declare(strict_types=1);

use App\Models\Finding;
use App\Models\PlatformUser;
use App\Models\Tenant;
use App\Services\Intune\AuditLogger;
use App\Services\OperationRunService;
use App\Services\Runbooks\FindingsLifecycleBackfillRunbookService;
use App\Services\Runbooks\FindingsLifecycleBackfillScope;
use App\Support\Auth\PlatformCapabilities;
use Filament\Facades\Filament;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

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

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

it('does not crash when audit logging fails and still finalizes a failed run', function () {
    $this->mock(AuditLogger::class, function ($mock): void {
        $mock->shouldReceive('log')->andThrow(new RuntimeException('audit unavailable'));
    });

    $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,
    ]);

    $user = PlatformUser::factory()->create([
        'capabilities' => [
            PlatformCapabilities::ACCESS_SYSTEM_PANEL,
            PlatformCapabilities::OPS_VIEW,
            PlatformCapabilities::RUNBOOKS_VIEW,
            PlatformCapabilities::RUNBOOKS_RUN,
            PlatformCapabilities::RUNBOOKS_FINDINGS_LIFECYCLE_BACKFILL,
        ],
        'is_active' => true,
    ]);

    $this->actingAs($user, 'platform');

    $runbook = app(FindingsLifecycleBackfillRunbookService::class);

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

    $runs = app(OperationRunService::class);

    $runs->updateRun(
        $run,
        status: 'completed',
        outcome: 'failed',
        failures: [
            [
                'code' => 'test.failed',
                'message' => 'Forced failure for audit fail-safe test.',
            ],
        ],
    );

    $runbook->maybeFinalize($run);

    $run->refresh();

    expect($run->status)->toBe('completed');
    expect($run->outcome)->toBe('failed');
});
