<?php

declare(strict_types=1);

use App\Filament\Pages\Reviews\CustomerReviewWorkspace;
use App\Filament\Resources\TenantReviewResource;
use App\Models\PlatformUser;
use App\Models\ReviewPack;
use App\Models\Tenant;
use App\Models\User;
use App\Services\Entitlements\WorkspaceCommercialLifecycleResolver;
use App\Services\Settings\SettingsWriter;
use App\Support\Auth\Capabilities;
use App\Support\Auth\PlatformCapabilities;
use App\Support\TenantReviewStatus;
use App\Support\Workspaces\WorkspaceContext;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Gate;
use Livewire\Livewire;

uses(RefreshDatabase::class);

function suspendCustomerReviewWorkspacePackAccessWorkspace(Tenant $tenant): void
{
    app(SettingsWriter::class)->updateWorkspaceCommercialLifecycle(
        actor: PlatformUser::factory()->create([
            'capabilities' => [
                PlatformCapabilities::ACCESS_SYSTEM_PANEL,
                PlatformCapabilities::DIRECTORY_VIEW,
                PlatformCapabilities::COMMERCIAL_LIFECYCLE_MANAGE,
            ],
            'is_active' => true,
        ]),
        workspace: $tenant->workspace,
        state: WorkspaceCommercialLifecycleResolver::STATE_SUSPENDED_READ_ONLY,
        reason: 'Customer review workspace suspended read-only test',
    );
}

it('keeps the latest released review as the only row action when a ready review pack exists', function (): void {
    $tenant = Tenant::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly');
    $snapshot = seedTenantReviewEvidence($tenant);

    $review = composeTenantReviewForTest($tenant, $user, $snapshot);
    $review->forceFill([
        'status' => TenantReviewStatus::Published->value,
        'published_at' => now(),
        'published_by_user_id' => (int) $user->getKey(),
    ])->save();

    $pack = ReviewPack::factory()->ready()->create([
        'tenant_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'tenant_review_id' => (int) $review->getKey(),
        'evidence_snapshot_id' => (int) $snapshot->getKey(),
        'initiated_by_user_id' => (int) $user->getKey(),
        'expires_at' => now()->addDay(),
    ]);

    $review->forceFill([
        'current_export_review_pack_id' => (int) $pack->getKey(),
    ])->save();

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

    Livewire::actingAs($user)
        ->test(CustomerReviewWorkspace::class)
        ->assertSee(TenantReviewResource::tenantScopedUrl('view', ['record' => $review->fresh()], $tenant), false)
        ->assertSee('Governance package')
        ->assertSee('Open review')
        ->assertDontSee('Download review pack')
        ->assertDontSee('Current review pack available');
});

it('keeps the customer review workspace row action visible while suspended read-only', function (): void {
    $tenant = Tenant::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly');
    $snapshot = seedTenantReviewEvidence($tenant);

    $review = composeTenantReviewForTest($tenant, $user, $snapshot);
    $review->forceFill([
        'status' => TenantReviewStatus::Published->value,
        'published_at' => now(),
        'published_by_user_id' => (int) $user->getKey(),
    ])->save();

    $pack = ReviewPack::factory()->ready()->create([
        'tenant_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'tenant_review_id' => (int) $review->getKey(),
        'evidence_snapshot_id' => (int) $snapshot->getKey(),
        'initiated_by_user_id' => (int) $user->getKey(),
        'expires_at' => now()->addDay(),
    ]);

    $review->forceFill([
        'current_export_review_pack_id' => (int) $pack->getKey(),
    ])->save();

    suspendCustomerReviewWorkspacePackAccessWorkspace($tenant);

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

    Livewire::actingAs($user)
        ->test(CustomerReviewWorkspace::class)
        ->assertSee(TenantReviewResource::tenantScopedUrl('view', ['record' => $review->fresh()], $tenant), false)
        ->assertSee('Open review')
        ->assertDontSee('Download review pack')
        ->assertDontSee('Current review pack available');
});

it('does not expose review-pack availability as a workspace row peer action', function (): void {
    $tenant = Tenant::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly');
    $snapshot = seedTenantReviewEvidence($tenant);

    $review = composeTenantReviewForTest($tenant, $user, $snapshot);
    $review->forceFill([
        'status' => TenantReviewStatus::Published->value,
        'published_at' => now(),
        'published_by_user_id' => (int) $user->getKey(),
        'current_export_review_pack_id' => null,
    ])->save();

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

    Livewire::actingAs($user)
        ->test(CustomerReviewWorkspace::class)
        ->assertSee(TenantReviewResource::tenantScopedUrl('view', ['record' => $review->fresh()], $tenant), false)
        ->assertSee('Unavailable')
        ->assertDontSee('No current review pack available yet')
        ->assertDontSee('Download review pack');
});

it('shows a partial governance-package state when the released review basis is limitation-aware', function (): void {
    $tenant = Tenant::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly');
    $snapshot = seedPartialTenantReviewEvidence($tenant);

    $review = composeTenantReviewForTest($tenant, $user, $snapshot);
    $review->forceFill([
        'status' => TenantReviewStatus::Published->value,
        'published_at' => now(),
        'published_by_user_id' => (int) $user->getKey(),
    ])->save();

    $pack = ReviewPack::factory()->ready()->create([
        'tenant_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'tenant_review_id' => (int) $review->getKey(),
        'evidence_snapshot_id' => (int) $snapshot->getKey(),
        'initiated_by_user_id' => (int) $user->getKey(),
        'expires_at' => now()->addDay(),
    ]);

    $review->forceFill([
        'current_export_review_pack_id' => (int) $pack->getKey(),
    ])->save();

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

    Livewire::actingAs($user)
        ->test(CustomerReviewWorkspace::class)
        ->assertSee(TenantReviewResource::tenantScopedUrl('view', ['record' => $review->fresh()], $tenant), false)
        ->assertSee('Partial')
        ->assertDontSee('Download review pack');
});

it('shows expired and capability-blocked governance-package states on the workspace row surface', function (): void {
    $expiredTenant = Tenant::factory()->create(['name' => 'Expired Pack Tenant']);
    [$user, $expiredTenant] = createUserWithTenant(tenant: $expiredTenant, role: 'readonly');
    $blockedTenant = Tenant::factory()->create([
        'workspace_id' => (int) $expiredTenant->workspace_id,
        'name' => 'Blocked Pack Tenant',
    ]);
    createUserWithTenant(tenant: $blockedTenant, user: $user, role: 'readonly');

    foreach ([$expiredTenant, $blockedTenant] as $tenant) {
        $snapshot = seedTenantReviewEvidence($tenant);
        $review = composeTenantReviewForTest($tenant, $user, $snapshot);
        $review->forceFill([
            'status' => TenantReviewStatus::Published->value,
            'published_at' => now(),
            'published_by_user_id' => (int) $user->getKey(),
        ])->save();

        $pack = ReviewPack::factory()->ready()->create([
            'tenant_id' => (int) $tenant->getKey(),
            'workspace_id' => (int) $tenant->workspace_id,
            'tenant_review_id' => (int) $review->getKey(),
            'evidence_snapshot_id' => (int) $snapshot->getKey(),
            'initiated_by_user_id' => (int) $user->getKey(),
            'expires_at' => $tenant->is($expiredTenant) ? now()->subDay() : now()->addDay(),
        ]);

        $review->forceFill(['current_export_review_pack_id' => (int) $pack->getKey()])->save();
    }

    Gate::define(Capabilities::REVIEW_PACK_VIEW, fn (User $actor, Tenant $tenant): bool => ! $tenant->is($blockedTenant));

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

    Livewire::actingAs($user)
        ->test(CustomerReviewWorkspace::class)
        ->assertCanSeeTableRecords([$expiredTenant->fresh(), $blockedTenant->fresh()])
        ->assertSee('Expired')
        ->assertSee('Blocked')
        ->assertDontSee('Download review pack');
});

it('hides tenants without a published review from the workspace rows', function (): void {
    $tenant = Tenant::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly');
    $snapshot = seedTenantReviewEvidence($tenant);

    $review = composeTenantReviewForTest($tenant, $user, $snapshot);
    $review->forceFill([
        'status' => TenantReviewStatus::Ready->value,
        'published_at' => null,
        'published_by_user_id' => null,
        'current_export_review_pack_id' => null,
    ])->save();

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

    Livewire::actingAs($user)
        ->test(CustomerReviewWorkspace::class)
        ->assertCanNotSeeTableRecords([$tenant->fresh()])
        ->assertSee('No released customer reviews match this view')
        ->assertDontSee('No published review available yet');
});
