<?php

declare(strict_types=1);

use App\Filament\Widgets\ManagedEnvironment\BaselineCompareCoverageBanner;
use App\Models\BaselineProfile;
use App\Models\BaselineSnapshot;
use App\Models\BaselineTenantAssignment;
use App\Models\Finding;
use App\Models\OperationRun;
use App\Support\Baselines\BaselineCompareReasonCode;
use App\Support\OperationRunOutcome;
use App\Support\OperationRunStatus;
use App\Support\OperationRunType;
use Filament\Facades\Filament;
use Livewire\Livewire;

function createCoverageBannerTenant(): array
{
    [$user, $tenant] = createUserWithTenant(role: 'owner');

    $profile = BaselineProfile::factory()->active()->create([
        'workspace_id' => (int) $tenant->workspace_id,
    ]);

    $snapshot = BaselineSnapshot::factory()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'baseline_profile_id' => (int) $profile->getKey(),
    ]);

    $profile->update(['active_snapshot_id' => (int) $snapshot->getKey()]);

    BaselineTenantAssignment::factory()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'managed_environment_id' => (int) $tenant->getKey(),
        'baseline_profile_id' => (int) $profile->getKey(),
    ]);

    return [$user, $tenant, $profile, $snapshot];
}

it('shows a cautionary coverage banner for suppressed baseline compare results', function (): void {
    [$user, $tenant, $profile, $snapshot] = createCoverageBannerTenant();
    $this->actingAs($user);

    OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'type' => OperationRunType::BaselineCompare->value,
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::PartiallySucceeded->value,
        'completed_at' => now(),
        'context' => [
            'baseline_profile_id' => (int) $profile->getKey(),
            'baseline_snapshot_id' => (int) $snapshot->getKey(),
            'baseline_compare' => [
                'reason_code' => BaselineCompareReasonCode::CoverageUnproven->value,
                'coverage' => [
                    'effective_types' => ['deviceConfiguration', 'deviceCompliancePolicy'],
                    'covered_types' => ['deviceConfiguration'],
                    'uncovered_types' => ['deviceCompliancePolicy'],
                    'proof' => false,
                ],
            ],
        ],
    ]);

    setAdminPanelContext($tenant);

    Livewire::test(BaselineCompareCoverageBanner::class)
        ->assertSee('The last compare finished, but normal result output was suppressed.')
        ->assertSee('Review compare detail');
});

it('shows an unavailable banner when no current baseline snapshot can be consumed', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');
    $this->actingAs($user);

    $profile = BaselineProfile::factory()->active()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'active_snapshot_id' => null,
    ]);

    BaselineTenantAssignment::factory()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'managed_environment_id' => (int) $tenant->getKey(),
        'baseline_profile_id' => (int) $profile->getKey(),
    ]);

    setAdminPanelContext($tenant);

    Livewire::test(BaselineCompareCoverageBanner::class)
        ->assertSee('The current baseline snapshot is not available for compare.')
        ->assertSee('Review baseline prerequisites');
});

it('does not render the banner for trustworthy no-drift results', function (): void {
    [$user, $tenant, $profile, $snapshot] = createCoverageBannerTenant();
    $this->actingAs($user);

    OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'type' => OperationRunType::BaselineCompare->value,
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::Succeeded->value,
        'completed_at' => now(),
        'context' => [
            'baseline_profile_id' => (int) $profile->getKey(),
            'baseline_snapshot_id' => (int) $snapshot->getKey(),
            'baseline_compare' => [
                'reason_code' => BaselineCompareReasonCode::NoDriftDetected->value,
                'coverage' => [
                    'effective_types' => ['deviceConfiguration'],
                    'covered_types' => ['deviceConfiguration'],
                    'uncovered_types' => [],
                    'proof' => true,
                ],
            ],
        ],
    ]);

    setAdminPanelContext($tenant);

    Livewire::test(BaselineCompareCoverageBanner::class)
        ->assertDontSee('No confirmed drift in the latest baseline compare.')
        ->assertDontSee('Review compare detail');
});

it('shows an action banner when overdue findings remain without new drift', function (): void {
    [$user, $tenant, $profile, $snapshot] = createCoverageBannerTenant();
    $this->actingAs($user);

    OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'type' => OperationRunType::BaselineCompare->value,
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::Succeeded->value,
        'completed_at' => now(),
        'context' => [
            'baseline_profile_id' => (int) $profile->getKey(),
            'baseline_snapshot_id' => (int) $snapshot->getKey(),
            'baseline_compare' => [
                'reason_code' => BaselineCompareReasonCode::NoDriftDetected->value,
                'coverage' => [
                    'effective_types' => ['deviceConfiguration'],
                    'covered_types' => ['deviceConfiguration'],
                    'uncovered_types' => [],
                    'proof' => true,
                ],
            ],
        ],
    ]);

    Finding::factory()->triaged()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'managed_environment_id' => (int) $tenant->getKey(),
        'due_at' => now()->subDay(),
    ]);

    setAdminPanelContext($tenant);

    Livewire::test(BaselineCompareCoverageBanner::class)
        ->assertSee('overdue finding')
        ->assertSee('Open findings');
});
