<?php

declare(strict_types=1);

use App\Filament\Pages\BaselineCompareLanding;
use App\Filament\Pages\Operations\TenantlessOperationRunViewer;
use App\Filament\Pages\Reviews\ReviewRegister;
use App\Filament\Resources\BaselineSnapshotResource;
use App\Filament\Resources\EnvironmentReviewResource;
use App\Models\BaselineProfile;
use App\Models\BaselineSnapshot;
use App\Models\ManagedEnvironment;
use App\Models\OperationRun;
use App\Models\User;
use App\Models\Workspace;
use App\Models\WorkspaceMembership;
use App\Services\Auth\WorkspaceCapabilityResolver;
use App\Support\Baselines\BaselineReasonCodes;
use App\Support\Workspaces\WorkspaceContext;
use Filament\Facades\Filament;
use Livewire\Livewire;

it('returns 404 for non-members on the baseline compare explanation surface', function (): void {
    [$member, $tenant] = createUserWithTenant(role: 'owner');
    $nonMember = User::factory()->create();

    $this->actingAs($nonMember)
        ->get(BaselineCompareLanding::getUrl(tenant: $tenant, panel: 'admin'))
        ->assertNotFound();
});

it('returns 403 for members missing the required capability on the canonical run detail surface', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    [$owner, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner');
    [$readonly] = createUserWithTenant(tenant: $tenant, user: User::factory()->create(), role: 'readonly');

    $run = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'type' => 'inventory_sync',
    ]);

    $this->actingAs($readonly)
        ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id])
        ->get(route('admin.operations.view', [
            'workspace' => $tenant->workspace,
            'run' => (int) $run->getKey(),
        ]))
        ->assertForbidden();
});

it('returns 403 for workspace members missing baseline snapshot visibility on explanation-first baseline capture surfaces', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

    WorkspaceMembership::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'user_id' => (int) $user->getKey(),
        'role' => 'readonly',
    ]);

    $profile = BaselineProfile::factory()->active()->create([
        'workspace_id' => (int) $workspace->getKey(),
    ]);

    $snapshot = BaselineSnapshot::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'baseline_profile_id' => (int) $profile->getKey(),
    ]);

    $resolver = \Mockery::mock(WorkspaceCapabilityResolver::class);
    $resolver->shouldReceive('isMember')->andReturnTrue();
    $resolver->shouldReceive('can')->andReturnFalse();
    app()->instance(WorkspaceCapabilityResolver::class, $resolver);

    $this->actingAs($user)
        ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()])
        ->get(BaselineSnapshotResource::getUrl('view', ['record' => $snapshot], panel: 'admin'))
        ->assertForbidden();
});

it('returns 404 for non-members on the environment review explanation detail surface', function (): void {
    $targetTenant = ManagedEnvironment::factory()->create();
    [$member] = createUserWithTenant(role: 'owner');
    $reviewOwner = User::factory()->create();
    createUserWithTenant(tenant: $targetTenant, user: $reviewOwner, role: 'owner');
    $review = composeEnvironmentReviewForTest($targetTenant, $reviewOwner);

    $this->actingAs($member)
        ->get(EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review], $targetTenant))
        ->assertNotFound();
});

it('returns 404 for workspace members without entitled tenant visibility on the review register explanation surface', function (): void {
    $workspace = Workspace::factory()->create();
    $user = User::factory()->create();

    WorkspaceMembership::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'user_id' => (int) $user->getKey(),
        'role' => 'owner',
    ]);

    $this->actingAs($user)
        ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()])
        ->get(ReviewRegister::getUrl(panel: 'admin'))
        ->assertNotFound();
});

it('renders governance summary facts for entitled viewers on the canonical run detail surface', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner');

    $run = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'type' => 'baseline_compare',
        'status' => 'completed',
        'outcome' => 'partially_succeeded',
        'context' => [
            'baseline_compare' => [
                'reason_code' => 'ambiguous_subjects',
                'evidence_gaps' => [
                    'count' => 2,
                ],
            ],
        ],
        'completed_at' => now(),
    ]);

    Filament::setTenant(null, true);
    $this->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]);
    session([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]);

    Livewire::actingAs($user)
        ->test(TenantlessOperationRunViewer::class, ['run' => $run])
        ->assertSee('Artifact impact')
        ->assertSee('Dominant cause')
        ->assertSee('Ambiguous matches');
});

it('allows entitled viewers to open blocked baseline-capture run detail surfaces', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner');

    $run = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'type' => 'baseline_capture',
        'status' => 'completed',
        'outcome' => 'blocked',
        'context' => [
            'reason_code' => BaselineReasonCodes::CAPTURE_INVENTORY_FAILED,
            'baseline_capture' => [
                'reason_code' => BaselineReasonCodes::CAPTURE_INVENTORY_FAILED,
                'current_baseline_changed' => false,
            ],
        ],
        'completed_at' => now(),
    ]);

    Filament::setTenant(null, true);
    $this->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]);
    session([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]);

    Livewire::actingAs($user)
        ->test(TenantlessOperationRunViewer::class, ['run' => $run])
        ->assertSee('Latest inventory sync failed');
});

it('keeps governance summary surfaces deny-as-not-found for workspace members without tenant entitlement', function (): void {
    $workspace = Workspace::factory()->create();
    $tenant = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'status' => 'active',
    ]);

    $user = User::factory()->create();

    WorkspaceMembership::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'user_id' => (int) $user->getKey(),
        'role' => 'owner',
    ]);

    $visibleTenant = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'status' => 'active',
    ]);

    $user->tenants()->syncWithoutDetaching([
        $visibleTenant->getKey() => ['role' => 'owner'],
    ]);

    $run = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $workspace->getKey(),
        'type' => 'environment.review_pack.generate',
        'status' => 'completed',
        'outcome' => 'succeeded',
        'completed_at' => now(),
    ]);

    $this->actingAs($user)
        ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()])
        ->get(route('admin.operations.view', [
            'workspace' => $workspace,
            'run' => (int) $run->getKey(),
        ]))
        ->assertNotFound();
});
