<?php

declare(strict_types=1);

use App\Filament\Pages\Reviews\ReviewRegister;
use App\Models\ManagedEnvironment;
use App\Models\User;
use App\Support\EnvironmentReviewCompletenessState;
use App\Support\EnvironmentReviewStatus;
use App\Support\Workspaces\WorkspaceContext;
use Livewire\Livewire;
use Tests\Feature\Concerns\BuildsGovernanceArtifactTruthFixtures;

uses(BuildsGovernanceArtifactTruthFixtures::class);

it('lists only entitled environment reviews in the canonical review register and filters by environment', function (): void {
    $tenantA = ManagedEnvironment::factory()->create(['name' => 'Alpha ManagedEnvironment']);
    [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner');

    $tenantB = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $tenantA->workspace_id,
        'name' => 'Beta ManagedEnvironment',
    ]);
    createUserWithTenant(tenant: $tenantB, user: $user, role: 'readonly');

    $tenantC = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $tenantA->workspace_id,
        'name' => 'Gamma ManagedEnvironment',
    ]);
    $foreignOwner = User::factory()->create();
    createUserWithTenant(tenant: $tenantC, user: $foreignOwner, role: 'owner');

    $reviewA = composeEnvironmentReviewForTest($tenantA, $user);
    $reviewB = composeEnvironmentReviewForTest($tenantB, $user);
    $reviewC = composeEnvironmentReviewForTest($tenantC, $foreignOwner);

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

    Livewire::withHeaders(['referer' => ReviewRegister::getUrl(panel: 'admin')])
        ->actingAs($user)
        ->test(ReviewRegister::class)
        ->assertSee('Outcome')
        ->assertDontSee('Monitoring landing')
        ->assertDontSee('Navigation lane')
        ->assertCanSeeTableRecords([$reviewA, $reviewB])
        ->assertCanNotSeeTableRecords([$reviewC])
        ->filterTable('managed_environment_id', (string) $tenantB->getKey())
        ->assertCanSeeTableRecords([$reviewB])
        ->assertCanNotSeeTableRecords([$reviewA, $reviewC]);
});

it('shows a single clear-filters empty-state action when no review rows match the current register view', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');
    $review = composeEnvironmentReviewForTest($tenant, $user);

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

    Livewire::withHeaders(['referer' => ReviewRegister::getUrl(panel: 'admin')])
        ->actingAs($user)
        ->test(ReviewRegister::class)
        ->searchTable('no-such-review-row')
        ->assertCanNotSeeTableRecords([$review])
        ->assertTableEmptyStateActionsExistInOrder(['clear_filters_empty'])
        ->assertSee('No review records match this view')
        ->assertSee('Clear filters');
});

it('clears only the page-level environment filter from the review register', function (): void {
    $tenantA = ManagedEnvironment::factory()->create(['name' => 'Alpha ManagedEnvironment']);
    [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner');

    $tenantB = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $tenantA->workspace_id,
        'name' => 'Beta ManagedEnvironment',
    ]);
    createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner');

    $reviewA = composeEnvironmentReviewForTest($tenantA, $user);
    $reviewB = composeEnvironmentReviewForTest($tenantB, $user);

    $this->actingAs($user);
    setAdminPanelContext();
    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenantA->workspace_id);
    session()->put(WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY, [
        (string) $tenantA->workspace_id => (int) $tenantA->getKey(),
    ]);

    $component = Livewire::withHeaders(['referer' => ReviewRegister::getUrl(panel: 'admin')])
        ->withQueryParams(['environment_id' => (int) $tenantA->getKey()])
        ->test(ReviewRegister::class)
        ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantA->getKey())
        ->assertActionVisible('clear_filters')
        ->assertCanSeeTableRecords([$reviewA])
        ->assertCanNotSeeTableRecords([$reviewB]);

    expect(app(WorkspaceContext::class)->lastEnvironmentId())->toBe((int) $tenantA->getKey());

    $component
        ->callAction('clear_filters')
        ->assertRedirect(ReviewRegister::getUrl(panel: 'admin'));

    Livewire::withHeaders(['referer' => ReviewRegister::getUrl(panel: 'admin')])
        ->withQueryParams([])
        ->actingAs($user)
        ->test(ReviewRegister::class)
        ->assertSet('tableFilters.managed_environment_id.value', null)
        ->assertCanSeeTableRecords([$reviewA, $reviewB]);

    expect(app(WorkspaceContext::class)->lastEnvironmentId())->toBe((int) $tenantA->getKey());
});

it('keeps stale and partial review rows aligned with environment review detail trust', function (): void {
    $staleTenant = ManagedEnvironment::factory()->create(['name' => 'Stale ManagedEnvironment']);
    [$user, $staleTenant] = createUserWithTenant(tenant: $staleTenant, role: 'owner');

    $partialTenant = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $staleTenant->workspace_id,
        'name' => 'Partial ManagedEnvironment',
    ]);
    createUserWithTenant(tenant: $partialTenant, user: $user, role: 'owner');

    $staleReview = $this->makeArtifactTruthReview(
        tenant: $staleTenant,
        user: $user,
        snapshot: seedStaleEnvironmentReviewEvidence($staleTenant),
        reviewOverrides: [
            'status' => EnvironmentReviewStatus::Published->value,
            'published_at' => now(),
            'published_by_user_id' => (int) $user->getKey(),
            'completeness_state' => EnvironmentReviewCompletenessState::Complete->value,
        ],
        summaryOverrides: [
            'publish_blockers' => [],
            'section_state_counts' => [
                'complete' => 6,
                'partial' => 0,
                'missing' => 0,
                'stale' => 0,
            ],
        ],
    );

    $partialReview = $this->makeArtifactTruthReview(
        tenant: $partialTenant,
        user: $user,
        snapshot: seedPartialEnvironmentReviewEvidence($partialTenant),
        reviewOverrides: [
            'status' => EnvironmentReviewStatus::Ready->value,
            'completeness_state' => EnvironmentReviewCompletenessState::Complete->value,
        ],
        summaryOverrides: [
            'publish_blockers' => [],
            'section_state_counts' => [
                'complete' => 6,
                'partial' => 0,
                'missing' => 0,
                'stale' => 0,
            ],
        ],
    );

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

    Livewire::withHeaders(['referer' => ReviewRegister::getUrl(panel: 'admin')])
        ->actingAs($user)
        ->test(ReviewRegister::class)
        ->assertCanSeeTableRecords([$staleReview, $partialReview])
        ->assertSee('Internal only')
        ->assertSee('Refresh the evidence basis before publishing this review')
        ->assertSee('Complete the evidence basis before publishing this review')
        ->assertDontSee('Publishable');
});
