<?php

declare(strict_types=1);

use App\Filament\Resources\EnvironmentReviewResource;
use App\Filament\Resources\EvidenceSnapshotResource;
use App\Filament\Resources\ReviewPackResource;
use App\Filament\Resources\StoredReportResource;
use App\Models\EnvironmentReview;
use App\Models\EvidenceSnapshot;
use App\Models\ManagedEnvironment;
use App\Models\ReviewPack;
use App\Models\StoredReport;
use App\Support\Workspaces\WorkspaceContext;

it('resolves review pack access from the remembered admin environment context', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', setUiContext: false);

    $otherTenant = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $tenant->workspace_id,
    ]);
    createUserWithTenant(tenant: $otherTenant, user: $user, role: 'owner', setUiContext: false);

    $pack = ReviewPack::factory()->ready()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'initiated_by_user_id' => (int) $user->getKey(),
    ]);

    $otherPack = ReviewPack::factory()->ready()->create([
        'managed_environment_id' => (int) $otherTenant->getKey(),
        'workspace_id' => (int) $otherTenant->workspace_id,
        'initiated_by_user_id' => (int) $user->getKey(),
    ]);

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

    expect(ReviewPackResource::canViewAny())->toBeTrue()
        ->and(ReviewPackResource::canView($pack))->toBeTrue()
        ->and(ReviewPackResource::canView($otherPack))->toBeFalse();
});

it('starts review pack generation from the remembered admin environment context', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', setUiContext: false);

    seedEnvironmentReviewEvidence($tenant);

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

    ReviewPackResource::executeGeneration([
        'include_pii' => true,
        'include_operations' => true,
    ]);

    $pack = ReviewPack::query()
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->where('workspace_id', (int) $tenant->workspace_id)
        ->latest('id')
        ->first();

    expect($pack)->toBeInstanceOf(ReviewPack::class)
        ->and($pack?->status)->toBeString();
});

it('starts environment review creation from the remembered admin environment context', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', setUiContext: false);

    $snapshot = seedEnvironmentReviewEvidence($tenant);

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

    EnvironmentReviewResource::executeCreateReview([
        'evidence_snapshot_id' => (string) $snapshot->getKey(),
    ]);

    $review = EnvironmentReview::query()
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->where('workspace_id', (int) $tenant->workspace_id)
        ->latest('id')
        ->first();

    expect($review)->toBeInstanceOf(EnvironmentReview::class)
        ->and((int) $review?->evidence_snapshot_id)->toBe((int) $snapshot->getKey());
});

it('starts evidence snapshot generation from the remembered admin environment context', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', setUiContext: false);

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

    EvidenceSnapshotResource::executeGeneration([
        'allow_stale' => false,
    ]);

    $snapshot = EvidenceSnapshot::query()
        ->where('managed_environment_id', (int) $tenant->getKey())
        ->where('workspace_id', (int) $tenant->workspace_id)
        ->latest('id')
        ->first();

    expect($snapshot)->toBeInstanceOf(EvidenceSnapshot::class)
        ->and((int) $snapshot?->managed_environment_id)->toBe((int) $tenant->getKey());
});

it('resolves stored report access from the remembered admin environment context', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', setUiContext: false);

    $otherTenant = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $tenant->workspace_id,
    ]);
    createUserWithTenant(tenant: $otherTenant, user: $user, role: 'owner', setUiContext: false);

    $report = StoredReport::factory()
        ->permissionPosture()
        ->create([
            'managed_environment_id' => (int) $tenant->getKey(),
            'workspace_id' => (int) $tenant->workspace_id,
        ]);

    $otherReport = StoredReport::factory()
        ->permissionPosture()
        ->create([
            'managed_environment_id' => (int) $otherTenant->getKey(),
            'workspace_id' => (int) $otherTenant->workspace_id,
        ]);

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

    expect(StoredReportResource::canViewAny())->toBeTrue()
        ->and(StoredReportResource::canView($report))->toBeTrue()
        ->and(StoredReportResource::canView($otherReport))->toBeFalse();
});
