<?php

declare(strict_types=1);

use App\Filament\Pages\Monitoring\FindingExceptionsQueue;
use App\Filament\Resources\EnvironmentReviewResource;
use App\Filament\Resources\EvidenceSnapshotResource;
use App\Filament\Resources\FindingExceptionResource;
use App\Filament\Resources\ManagedEnvironmentResource;
use App\Models\EvidenceSnapshot;
use App\Models\Finding;
use App\Models\FindingException;
use App\Models\ManagedEnvironment;
use App\Models\OperationRun;
use App\Models\PlatformUser;
use App\Models\ReviewPack;
use App\Models\User;
use App\Services\Findings\FindingExceptionService;
use App\Support\Auth\PlatformCapabilities;
use App\Support\EnvironmentReviewCompletenessState;
use App\Support\EnvironmentReviewStatus;
use App\Support\Evidence\EvidenceCompletenessState;
use App\Support\Evidence\EvidenceSnapshotStatus;
use App\Support\OperationRunOutcome;
use App\Support\OperationRunStatus;
use App\Support\System\SystemOperationRunLinks;
use Illuminate\Foundation\Testing\RefreshDatabase;

pest()->browser()->timeout(20_000);

uses(RefreshDatabase::class);

function spec194ApprovedFindingException(ManagedEnvironment $tenant, User $requester): FindingException
{
    $approver = User::factory()->create();
    createUserWithTenant(
        tenant: $tenant,
        user: $approver,
        role: 'owner',
        workspaceRole: 'manager',
        ensureDefaultMicrosoftProviderConnection: false,
    );

    $finding = Finding::factory()->for($tenant)->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'status' => Finding::STATUS_RISK_ACCEPTED,
    ]);

    /** @var FindingExceptionService $service */
    $service = app(FindingExceptionService::class);

    $requested = $service->request($finding, $tenant, $requester, [
        'owner_user_id' => (int) $requester->getKey(),
        'request_reason' => 'Spec194 browser smoke request.',
        'review_due_at' => now()->addDays(7)->toDateTimeString(),
        'expires_at' => now()->addDays(14)->toDateTimeString(),
    ]);

    return $service->approve($requested, $approver, [
        'effective_from' => now()->subDay()->toDateTimeString(),
        'expires_at' => now()->addDays(14)->toDateTimeString(),
        'approval_reason' => 'Spec194 browser smoke approval.',
    ]);
}

function spec194SmokeLoginUrl(User $user, ManagedEnvironment $tenant, string $redirect = ''): string
{
    $redirect = spec194RelativeRedirect($redirect);

    return route('admin.local.smoke-login', array_filter([
        'email' => $user->email,
        'tenant' => $tenant->external_id,
        'workspace' => $tenant->workspace->slug,
        'redirect' => $redirect,
    ], static fn (?string $value): bool => filled($value)));
}

function spec194RelativeRedirect(string $redirect): string
{
    $redirect = trim($redirect);

    if ($redirect === '') {
        return '';
    }

    $parts = parse_url($redirect);

    if ($parts === false || ! isset($parts['path'])) {
        return '';
    }

    return $parts['path']
        .(isset($parts['query']) ? '?'.$parts['query'] : '')
        .(isset($parts['fragment']) ? '#'.$parts['fragment'] : '');
}

it('smokes tenant and admin governance semantics through modal entry points', function (): void {
    [$user, $tenant] = createUserWithTenant(
        role: 'owner',
        workspaceRole: 'owner',
        ensureDefaultMicrosoftProviderConnection: false,
        clearCapabilityCaches: true,
    );

    $finding = Finding::factory()->for($tenant)->create();

    $pendingException = FindingException::query()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'managed_environment_id' => (int) $tenant->getKey(),
        'finding_id' => (int) $finding->getKey(),
        'requested_by_user_id' => (int) $user->getKey(),
        'owner_user_id' => (int) $user->getKey(),
        'status' => FindingException::STATUS_PENDING,
        'current_validity_state' => FindingException::VALIDITY_MISSING_SUPPORT,
        'request_reason' => 'Spec194 focused review queue smoke.',
        'requested_at' => now()->subDay(),
        'review_due_at' => now()->addDay(),
        'evidence_summary' => ['reference_count' => 0],
    ]);

    $approvedException = spec194ApprovedFindingException($tenant, $user);

    $snapshotRun = OperationRun::factory()->forTenant($tenant)->create([
        'workspace_id' => (int) $tenant->workspace_id,
    ]);

    $snapshot = EvidenceSnapshot::query()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'operation_run_id' => (int) $snapshotRun->getKey(),
        'initiated_by_user_id' => (int) $user->getKey(),
        'status' => EvidenceSnapshotStatus::Active->value,
        'completeness_state' => EvidenceCompletenessState::Complete->value,
        'summary' => ['finding_count' => 2],
        'generated_at' => now(),
    ]);

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

    $review = composeEnvironmentReviewForTest($tenant, $user, $snapshot);

    $review->forceFill([
        'status' => EnvironmentReviewStatus::Ready->value,
        'completeness_state' => EnvironmentReviewCompletenessState::Complete->value,
        'summary' => array_replace_recursive(is_array($review->summary) ? $review->summary : [], [
            'publish_blockers' => [],
            'section_state_counts' => [
                'complete' => 6,
                'partial' => 0,
                'missing' => 0,
                'stale' => 0,
            ],
        ]),
    ])->save();

    $review = $review->refresh();

    $archivedTenant = ManagedEnvironment::factory()->archived()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'name' => 'Spec194 Archived ManagedEnvironment',
    ]);

    createUserWithTenant(
        tenant: $archivedTenant,
        user: $user,
        role: 'owner',
        workspaceRole: 'owner',
        ensureDefaultMicrosoftProviderConnection: false,
        clearCapabilityCaches: true,
    );

    visit(spec194SmokeLoginUrl($user, $tenant))
        ->waitForText($tenant->name)
        ->assertNoJavaScriptErrors()
        ->assertNoConsoleLogs();

    visit(FindingExceptionsQueue::getUrl(panel: 'admin').'?exception='.(int) $pendingException->getKey())
        ->waitForText('Focused review lane')
        ->assertNoJavaScriptErrors()
        ->assertNoConsoleLogs()
        ->assertSee('Selection-bound decisions now define the active work lane.')
        ->assertSee('Approve exception')
        ->assertSee('Reject exception');

    visit(FindingExceptionResource::getUrl('view', ['record' => $approvedException], tenant: $tenant))
        ->waitForText('Related context')
        ->assertNoJavaScriptErrors()
        ->assertNoConsoleLogs()
        ->assertSee('Renew exception')
        ->assertSee('Revoke exception');

    visit(EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review], $tenant))
        ->waitForText('Related context')
        ->assertNoJavaScriptErrors()
        ->assertNoConsoleLogs()
        ->click('Publish review')
        ->waitForText('Publication reason')
        ->click('button:has-text("Cancel")')
        ->click('[aria-label="More"]')
        ->assertSee('Refresh review')
        ->assertSee('Export executive pack')
        ->click('[aria-label="Danger"]')
        ->click('Archive review')
        ->waitForText('Archive reason')
        ->click('button:has-text("Cancel")')
        ->assertSee('Publish review')
        ->assertSee('Evidence snapshot');

    visit(EvidenceSnapshotResource::getUrl('view', ['record' => $snapshot], tenant: $tenant))
        ->waitForText('Related context')
        ->assertNoJavaScriptErrors()
        ->assertNoConsoleLogs()
        ->click('Refresh evidence')
        ->waitForText('Confirm')
        ->click('button:has-text("Cancel")')
        ->click('Expire snapshot')
        ->waitForText('Expiry reason')
        ->click('button:has-text("Cancel")')
        ->assertSee('Refresh evidence')
        ->assertSee('Expire snapshot');

    visit(ManagedEnvironmentResource::getUrl('view', ['record' => $tenant], panel: 'admin'))
        ->waitForText('Environment governance overview')
        ->assertNoJavaScriptErrors()
        ->assertNoConsoleLogs()
        ->assertSee((string) $tenant->name)
        ->assertSee('Recommended next actions');

    visit(ManagedEnvironmentResource::getUrl('edit', ['record' => $tenant], panel: 'admin'))
        ->waitForText('Environment governance overview')
        ->assertNoJavaScriptErrors()
        ->assertNoConsoleLogs()
        ->assertSee((string) $tenant->name);

    visit(spec194SmokeLoginUrl(
        $user,
        $archivedTenant,
        ManagedEnvironmentResource::getUrl('view', ['record' => $archivedTenant], panel: 'admin'),
    ))
        ->waitForText('Environment governance overview')
        ->assertNoJavaScriptErrors()
        ->assertNoConsoleLogs()
        ->assertSee((string) $archivedTenant->name);

    visit(spec194SmokeLoginUrl(
        $user,
        $archivedTenant,
        ManagedEnvironmentResource::getUrl('edit', ['record' => $archivedTenant], panel: 'admin'),
    ))
        ->waitForText('Environment governance overview')
        ->assertNoJavaScriptErrors()
        ->assertNoConsoleLogs()
        ->assertSee((string) $archivedTenant->name);
});

it('smokes system run triage semantics without javascript errors', function (): void {
    $failedRun = OperationRun::factory()->create([
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::Failed->value,
        'type' => 'inventory_sync',
    ]);

    $runningRun = OperationRun::factory()->create([
        'status' => OperationRunStatus::Running->value,
        'outcome' => OperationRunOutcome::Pending->value,
        'type' => 'inventory_sync',
        'created_at' => now()->subMinutes(15),
        'started_at' => now()->subMinutes(10),
    ]);

    $platformUser = PlatformUser::factory()->create([
        'capabilities' => [
            PlatformCapabilities::ACCESS_SYSTEM_PANEL,
            PlatformCapabilities::OPERATIONS_VIEW,
            PlatformCapabilities::OPERATIONS_MANAGE,
        ],
        'is_active' => true,
    ]);

    auth('web')->logout();
    $this->flushSession();
    $this->actingAs($platformUser, 'platform');

    visit(SystemOperationRunLinks::view($failedRun))
        ->waitForText('Operation #'.(int) $failedRun->getKey())
        ->assertNoJavaScriptErrors()
        ->assertNoConsoleLogs()
        ->assertSee('Retry')
        ->assertSee('Mark investigated')
        ->assertDontSee('Cancel');

    visit(SystemOperationRunLinks::view($runningRun))
        ->waitForText('Operation #'.(int) $runningRun->getKey())
        ->assertNoJavaScriptErrors()
        ->assertNoConsoleLogs()
        ->assertSee('Mark investigated')
        ->assertSee('Cancel');
});
