<?php

declare(strict_types=1);

use App\Filament\Widgets\Dashboard\BaselineCompareNow;
use App\Filament\Widgets\Dashboard\NeedsAttention;
use App\Models\BackupItem;
use App\Models\BackupSchedule;
use App\Models\BackupSet;
use App\Models\BaselineProfile;
use App\Models\BaselineSnapshot;
use App\Models\BaselineTenantAssignment;
use App\Models\Finding;
use App\Models\FindingException;
use App\Models\OperationRun;
use App\Models\RestoreRun;
use App\Support\Baselines\BaselineCompareReasonCode;
use App\Support\OperationRunOutcome;
use App\Support\OperationRunStatus;
use App\Support\OperationRunType;
use Carbon\CarbonImmutable;
use Filament\Facades\Filament;
use Livewire\Livewire;

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

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

    $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];
}

function seedTrustworthyCompare(array $tenantContext): void
{
    [$user, $tenant, $profile, $snapshot] = $tenantContext;

    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()->subHour(),
        '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,
                ],
            ],
        ],
    ]);
}

afterEach(function (): void {
    CarbonImmutable::setTestNow();
});

it('suppresses calm dashboard wording when stale and terminal operations both need attention', function (): void {
    $tenantContext = createTruthAlignedDashboardTenant();
    [$user, $tenant] = $tenantContext;
    $this->actingAs($user);

    seedTrustworthyCompare($tenantContext);

    OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'type' => 'inventory_sync',
        'status' => OperationRunStatus::Queued->value,
        'outcome' => OperationRunOutcome::Pending->value,
        'created_at' => now()->subHour(),
    ]);

    OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'type' => 'policy.sync',
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::Failed->value,
    ]);

    setAdminPanelContext($tenant);

    Livewire::test(NeedsAttention::class)
        ->assertSee('Active operations look stale')
        ->assertSee('Terminal operations need follow-up')
        ->assertSee('Open stale operations')
        ->assertSee('Open terminal follow-up')
        ->assertDontSee('Current governance and findings signals look trustworthy.');

    Livewire::test(BaselineCompareNow::class)
        ->assertSee('Action required')
        ->assertSee('operation')
        ->assertSee('Open operations')
        ->assertDontSee('Aligned');
});

it('suppresses compare calmness when high-severity active findings remain open', function (): void {
    $tenantContext = createTruthAlignedDashboardTenant();
    [$user, $tenant] = $tenantContext;
    $this->actingAs($user);

    seedTrustworthyCompare($tenantContext);

    Finding::factory()->for($tenant)->create([
        'status' => Finding::STATUS_TRIAGED,
        'severity' => Finding::SEVERITY_CRITICAL,
        'finding_type' => Finding::FINDING_TYPE_PERMISSION_POSTURE,
    ]);

    setAdminPanelContext($tenant);

    Livewire::test(NeedsAttention::class)
        ->assertSee('High severity active findings')
        ->assertSee('Open findings')
        ->assertDontSee('Current governance and findings signals look trustworthy.');

    Livewire::test(BaselineCompareNow::class)
        ->assertSee('Action required')
        ->assertSee('high-severity active finding')
        ->assertSee('Open findings')
        ->assertDontSee('Aligned');
});

it('keeps healthy operations-only activity separate from governance attention', function (): void {
    $tenantContext = createTruthAlignedDashboardTenant();
    [$user, $tenant] = $tenantContext;
    $this->actingAs($user);

    seedTrustworthyCompare($tenantContext);

    $healthyBackup = BackupSet::factory()->for($tenant)->create([
        'name' => 'Healthy truth-aligned backup',
        'item_count' => 1,
        'completed_at' => now()->subMinutes(30),
    ]);

    BackupItem::factory()->for($tenant)->for($healthyBackup)->create([
        'payload' => ['id' => 'healthy-policy'],
        'metadata' => [],
        'assignments' => [],
    ]);

        RestoreRun::factory()
            ->for($tenant)
            ->for($healthyBackup)
            ->completedOutcome()
            ->create([
                'completed_at' => now()->subMinutes(10),
            ]);

    OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'type' => 'inventory_sync',
        'status' => OperationRunStatus::Running->value,
        'outcome' => OperationRunOutcome::Pending->value,
        'created_at' => now()->subMinute(),
        'started_at' => now()->subMinute(),
    ]);

    setAdminPanelContext($tenant);

    Livewire::test(NeedsAttention::class)
        ->assertSee('Current governance and findings signals look trustworthy.')
        ->assertSee('Operations are active')
        ->assertDontSee('Terminal operations need follow-up')
        ->assertDontSee('Active operations look stale');

    Livewire::test(BaselineCompareNow::class)
        ->assertSee('Aligned')
        ->assertSee('No action needed')
        ->assertDontSee('Action required');
});

it('keeps overdue and governance-lapsed attention actionable without falling back to calm wording', function (): void {
    $tenantContext = createTruthAlignedDashboardTenant();
    [$user, $tenant] = $tenantContext;
    $this->actingAs($user);

    seedTrustworthyCompare($tenantContext);

    Finding::factory()->for($tenant)->create([
        'status' => Finding::STATUS_TRIAGED,
        'due_at' => now()->subDay(),
    ]);

    $lapsedFinding = Finding::factory()->for($tenant)->create([
        'status' => Finding::STATUS_RISK_ACCEPTED,
    ]);

    FindingException::query()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'managed_environment_id' => (int) $tenant->getKey(),
        'finding_id' => (int) $lapsedFinding->getKey(),
        'requested_by_user_id' => (int) $user->getKey(),
        'owner_user_id' => (int) $user->getKey(),
        'approved_by_user_id' => (int) $user->getKey(),
        'status' => FindingException::STATUS_ACTIVE,
        'current_validity_state' => FindingException::VALIDITY_MISSING_SUPPORT,
        'request_reason' => 'Lapsed governance',
        'approval_reason' => 'Approved',
        'requested_at' => now()->subDays(5),
        'approved_at' => now()->subDays(4),
        'effective_from' => now()->subDays(4),
        'review_due_at' => now()->subDay(),
        'expires_at' => now()->subDay(),
        'evidence_summary' => ['reference_count' => 0],
    ]);

    setAdminPanelContext($tenant);

    Livewire::test(NeedsAttention::class)
        ->assertSee('Overdue findings')
        ->assertSee('Lapsed accepted-risk governance')
        ->assertSee('Open findings')
        ->assertDontSee('Current governance and findings signals look trustworthy.');

    Livewire::test(BaselineCompareNow::class)
        ->assertSee('Action required')
        ->assertSee('Open findings')
        ->assertDontSee('Aligned');
});

it('suppresses calm dashboard wording when the latest backup basis is stale even if older history looked healthier', function (): void {
    CarbonImmutable::setTestNow(CarbonImmutable::create(2026, 4, 7, 12, 0, 0, 'UTC'));

    $tenantContext = createTruthAlignedDashboardTenant();
    [$user, $tenant] = $tenantContext;
    $this->actingAs($user);

    seedTrustworthyCompare($tenantContext);

    $olderHealthy = BackupSet::factory()->for($tenant)->create([
        'name' => 'Older healthy backup',
        'item_count' => 1,
        'completed_at' => now()->subDays(3),
    ]);

    BackupItem::factory()->for($tenant)->for($olderHealthy)->create([
        'payload' => ['id' => 'healthy-policy'],
        'metadata' => [],
        'assignments' => [],
    ]);

    $latestStale = BackupSet::factory()->for($tenant)->create([
        'name' => 'Latest stale backup',
        'item_count' => 1,
        'completed_at' => now()->subDays(2),
    ]);

    BackupItem::factory()->for($tenant)->for($latestStale)->create([
        'payload' => ['id' => 'stale-policy'],
        'metadata' => [],
        'assignments' => [],
    ]);

    setAdminPanelContext($tenant);

    Livewire::test(NeedsAttention::class)
        ->assertSee('Latest backup is stale')
        ->assertDontSee('Backups are recent and healthy')
        ->assertDontSee('Current governance and findings signals look trustworthy.');
});

it('adds positive backup calmness only when the latest backup basis is recent, clean, and schedules do not need follow-up', function (): void {
    CarbonImmutable::setTestNow(CarbonImmutable::create(2026, 4, 7, 12, 0, 0, 'UTC'));

    $tenantContext = createTruthAlignedDashboardTenant();
    [$user, $tenant] = $tenantContext;
    $this->actingAs($user);

    seedTrustworthyCompare($tenantContext);

    $healthyBackup = BackupSet::factory()->for($tenant)->create([
        'name' => 'Healthy backup',
        'item_count' => 1,
        'completed_at' => now()->subMinutes(20),
    ]);

    BackupItem::factory()->for($tenant)->for($healthyBackup)->create([
        'payload' => ['id' => 'healthy-policy'],
        'metadata' => [],
        'assignments' => [],
    ]);

        RestoreRun::factory()
            ->for($tenant)
            ->for($healthyBackup)
            ->completedOutcome()
            ->create([
                'completed_at' => now()->subMinutes(10),
            ]);

    setAdminPanelContext($tenant);

    Livewire::test(NeedsAttention::class)
        ->assertSee('Backups are recent and healthy')
        ->assertDontSee('Backup schedules need follow-up');

    BackupSchedule::query()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'name' => 'Overdue dashboard schedule',
        'is_enabled' => true,
        'timezone' => 'UTC',
        'frequency' => 'daily',
        'time_of_day' => '01:00:00',
        'days_of_week' => null,
        'policy_types' => ['deviceConfiguration'],
        'include_foundations' => true,
        'retention_keep_last' => 30,
        'last_run_at' => null,
        'last_run_status' => null,
        'next_run_at' => now()->subHours(2),
    ]);

    Livewire::test(NeedsAttention::class)
        ->assertSee('Backup schedules need follow-up')
        ->assertDontSee('Backups are recent and healthy');
});
