<?php

declare(strict_types=1);

use App\Filament\Pages\Monitoring\FindingExceptionsQueue;
use App\Models\Finding;
use App\Models\FindingException;
use App\Support\Workspaces\WorkspaceContext;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;

uses(RefreshDatabase::class);

it('renders a quiet monitoring state when no exception is selected', function (): void {
    [$approver, $tenant] = createUserWithTenant(role: 'owner', workspaceRole: 'manager');

    $finding = Finding::factory()->for($tenant)->create();

    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) $approver->getKey(),
        'owner_user_id' => (int) $approver->getKey(),
        'status' => FindingException::STATUS_PENDING,
        'current_validity_state' => FindingException::VALIDITY_MISSING_SUPPORT,
        'request_reason' => 'Queue hierarchy review lane',
        'requested_at' => now()->subDay(),
        'review_due_at' => now()->addDay(),
        'evidence_summary' => ['reference_count' => 0],
    ]);

    $this->actingAs($approver);
    setAdminPanelContext();
    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);

    Livewire::test(FindingExceptionsQueue::class)
        ->assertSee('Quiet monitoring mode')
        ->assertSee('Inspect an exception to enter the focused review lane.')
        ->assertDontSee('Focused review lane')
        ->assertActionHidden('approve_selected_exception')
        ->assertActionHidden('reject_selected_exception');
});

it('renders a focused review lane when a pending exception is selected', function (): void {
    [$approver, $tenant] = createUserWithTenant(role: 'owner', workspaceRole: 'manager');

    $finding = Finding::factory()->for($tenant)->create();

    $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) $approver->getKey(),
        'owner_user_id' => (int) $approver->getKey(),
        'status' => FindingException::STATUS_PENDING,
        'current_validity_state' => FindingException::VALIDITY_MISSING_SUPPORT,
        'request_reason' => 'Focused review lane request',
        'requested_at' => now()->subDay(),
        'review_due_at' => now()->addDay(),
        'evidence_summary' => ['reference_count' => 0],
    ]);

    $this->actingAs($approver);
    setAdminPanelContext();
    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);

    Livewire::withQueryParams([
        'exception' => (int) $exception->getKey(),
    ])
        ->test(FindingExceptionsQueue::class)
        ->assertSet('selectedFindingExceptionId', (int) $exception->getKey())
        ->assertSee('Focused review lane')
        ->assertSee('Decision lane')
        ->assertSee('Related drilldown')
        ->assertDontSee('Quiet monitoring mode')
        ->assertActionVisible('clear_selected_exception')
        ->assertActionVisible('approve_selected_exception')
        ->assertActionVisible('reject_selected_exception')
        ->mountAction('approve_selected_exception')
        ->assertActionMounted('approve_selected_exception')
        ->callMountedAction()
        ->assertHasActionErrors(['approval_reason']);

    Livewire::withQueryParams([
        'exception' => (int) $exception->getKey(),
    ])
        ->test(FindingExceptionsQueue::class)
        ->mountAction('reject_selected_exception')
        ->assertActionMounted('reject_selected_exception')
        ->callMountedAction()
        ->assertHasActionErrors(['rejection_reason']);
});

it('falls back to quiet monitoring when the requested exception is invalid or unauthorized', function (): void {
    [$approver, $tenant] = createUserWithTenant(role: 'owner', workspaceRole: 'manager');

    $foreignTenant = \App\Models\ManagedEnvironment::factory()->create();
    [$foreignRequester] = createUserWithTenant(tenant: $foreignTenant, role: 'owner');

    $foreignFinding = Finding::factory()->for($foreignTenant)->create();

    $foreignException = FindingException::query()->create([
        'workspace_id' => (int) $foreignTenant->workspace_id,
        'managed_environment_id' => (int) $foreignTenant->getKey(),
        'finding_id' => (int) $foreignFinding->getKey(),
        'requested_by_user_id' => (int) $foreignRequester->getKey(),
        'owner_user_id' => (int) $foreignRequester->getKey(),
        'status' => FindingException::STATUS_PENDING,
        'current_validity_state' => FindingException::VALIDITY_MISSING_SUPPORT,
        'request_reason' => 'Foreign queue exception',
        'requested_at' => now()->subDay(),
        'review_due_at' => now()->addDay(),
        'evidence_summary' => ['reference_count' => 0],
    ]);

    $this->actingAs($approver);
    setAdminPanelContext();
    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);

    Livewire::withQueryParams(['exception' => 999999])
        ->test(FindingExceptionsQueue::class)
        ->assertSet('selectedFindingExceptionId', null)
        ->assertSee('Quiet monitoring mode')
        ->assertActionHidden('clear_selected_exception');

    Livewire::withQueryParams(['exception' => (int) $foreignException->getKey()])
        ->test(FindingExceptionsQueue::class)
        ->assertSet('selectedFindingExceptionId', null)
        ->assertSee('Quiet monitoring mode')
        ->assertActionHidden('clear_selected_exception');
});
