<?php

declare(strict_types=1);

use App\Filament\Pages\Governance\DecisionRegister;
use App\Filament\Resources\FindingExceptionResource;
use App\Models\Finding;
use App\Models\FindingException;
use App\Models\FindingExceptionDecision;
use App\Models\ManagedEnvironment;
use App\Support\Navigation\CanonicalNavigationContext;
use App\Support\Workspaces\WorkspaceContext;
use Filament\Facades\Filament;
use Livewire\Livewire;

it('embeds decision register navigation context into open decision links', function (): void {
    $tenant = ManagedEnvironment::factory()->create([
        'status' => 'active',
        'name' => 'Alpha ManagedEnvironment',
        'external_id' => 'alpha-tenant',
    ]);
    [$user, $tenant] = createUserWithTenant($tenant, role: 'owner', workspaceRole: 'owner');

    $finding = Finding::factory()
        ->for($tenant)
        ->riskAccepted()
        ->create([
            'workspace_id' => (int) $tenant->workspace_id,
        ]);

    $exception = FindingException::query()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'managed_environment_id' => (int) $tenant->getKey(),
        'finding_id' => (int) $finding->getKey(),
        'requested_by_user_id' => (int) $user->getKey(),
        'owner_user_id' => (int) $user->getKey(),
        'status' => FindingException::STATUS_PENDING,
        'current_validity_state' => FindingException::VALIDITY_MISSING_SUPPORT,
        'request_reason' => 'Decision register continuity',
        'requested_at' => now()->subDay(),
        'review_due_at' => now()->addDay(),
        'evidence_summary' => ['reference_count' => 0],
    ]);

    $decision = $exception->decisions()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'managed_environment_id' => (int) $tenant->getKey(),
        'actor_user_id' => (int) $user->getKey(),
        'decision_type' => FindingExceptionDecision::TYPE_REQUESTED,
        'reason' => 'Decision register continuity',
        'metadata' => [],
        'decided_at' => now()->subDay(),
    ]);

    $exception->forceFill(['current_decision_id' => (int) $decision->getKey()])->save();

    $context = CanonicalNavigationContext::forDecisionRegister(
        canonicalRouteName: DecisionRegister::getRouteName(),
        tenantId: (int) $tenant->getKey(),
        backLinkUrl: DecisionRegister::getUrl(panel: 'admin', parameters: [
            'managed_environment_id' => (string) $tenant->getKey(),
        ]),
    );

    $expectedDetailUrl =
        FindingExceptionResource::getUrl('view', ['record' => $exception], panel: 'admin', tenant: $tenant)
        .'?'.http_build_query($context->toQuery());

    $this->actingAs($user);
    Filament::setCurrentPanel('admin');
    Filament::setTenant(null, true);
    Filament::bootCurrentPanel();
    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);

    $component = Livewire::withQueryParams([
        'managed_environment_id' => (string) $tenant->getKey(),
    ])
        ->actingAs($user)
        ->test(DecisionRegister::class)
        ->assertSee('Decision register')
        ->assertSee('Open decision');

    expect($component->instance()->decisionUrl($exception))
        ->toBe($expectedDetailUrl)
        ->toContain('nav%5Bback_label%5D=Back+to+decision+register')
        ->toContain('nav%5Bsource_surface%5D=governance.decision_register');
});