<?php

declare(strict_types=1);

use App\Filament\Pages\Reviews\ReviewRegister;
use App\Models\Tenant;
use App\Models\User;
use App\Support\TenantReviewCompletenessState;
use App\Support\TenantReviewStatus;
use App\Support\Workspaces\WorkspaceContext;
use Livewire\Livewire;
use Tests\Feature\Concerns\BuildsGovernanceArtifactTruthFixtures;

uses(BuildsGovernanceArtifactTruthFixtures::class);

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

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

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

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

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

    Livewire::actingAs($user)
        ->test(ReviewRegister::class)
        ->assertSee('Outcome')
        ->assertDontSee('Monitoring landing')
        ->assertDontSee('Navigation lane')
        ->assertCanSeeTableRecords([$reviewA, $reviewB])
        ->assertCanNotSeeTableRecords([$reviewC])
        ->filterTable('tenant_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 = composeTenantReviewForTest($tenant, $user);

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

    Livewire::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 the remembered tenant prefilter from the review register', function (): void {
    $tenantA = Tenant::factory()->create(['name' => 'Alpha Tenant']);
    [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner');

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

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

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

    $component = Livewire::actingAs($user)
        ->test(ReviewRegister::class)
        ->assertActionVisible('clear_filters')
        ->assertCanSeeTableRecords([$reviewA])
        ->assertCanNotSeeTableRecords([$reviewB]);

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

    $component
        ->callAction('clear_filters')
        ->assertActionHidden('clear_filters')
        ->assertCanSeeTableRecords([$reviewA, $reviewB]);

    expect(app(WorkspaceContext::class)->lastTenantId())->toBeNull();
});

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

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

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

    $partialReview = $this->makeArtifactTruthReview(
        tenant: $partialTenant,
        user: $user,
        snapshot: seedPartialTenantReviewEvidence($partialTenant),
        reviewOverrides: [
            'status' => TenantReviewStatus::Ready->value,
            'completeness_state' => TenantReviewCompletenessState::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::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');
});
