<?php

declare(strict_types=1);

use App\Filament\Pages\EnvironmentDashboard;
use App\Filament\Resources\ManagedEnvironmentResource;
use App\Support\BackupHealth\TenantBackupHealthAssessment;
use App\Support\PortfolioTriage\PortfolioArrivalContextToken;
use App\Support\RestoreSafety\RestoreResultAttention;
use App\Support\Tenants\TenantRecoveryTriagePresentation;
use Tests\Feature\Concerns\BuildsPortfolioTriageFixtures;

uses(BuildsPortfolioTriageFixtures::class);

function tenantRegistryArrivalStateFromUrl(string $url): ?array
{
    parse_str((string) parse_url($url, PHP_URL_QUERY), $query);

    return PortfolioArrivalContextToken::decode($query[PortfolioArrivalContextToken::QUERY_PARAMETER] ?? null);
}

it('adds arrival context and bounded return state to triage-driven tenant opens', function (): void {
    [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor ManagedEnvironment');
    $weakenedTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Weakened ManagedEnvironment');
    $backupSet = $this->seedPortfolioBackupConcern($weakenedTenant, TenantBackupHealthAssessment::POSTURE_STALE);
    $this->seedPortfolioRecoveryConcern($weakenedTenant, RestoreResultAttention::STATE_COMPLETED_WITH_FOLLOW_UP, $backupSet);

    $triageState = [
        'backup_posture' => [TenantBackupHealthAssessment::POSTURE_STALE],
        'recovery_evidence' => [TenantRecoveryTriagePresentation::RECOVERY_EVIDENCE_WEAKENED],
        'triage_sort' => TenantRecoveryTriagePresentation::TRIAGE_SORT_WORST_FIRST,
    ];

    $this->usePortfolioTriageWorkspace($user, $anchorTenant);

    $expectedUrl = ManagedEnvironmentResource::tenantDashboardOpenUrl($weakenedTenant, $triageState);

    $this->portfolioTriageRegistryList($user, $anchorTenant, $triageState)
        ->assertTableActionHasUrl('openTenant', $expectedUrl, $weakenedTenant);

    expect(tenantRegistryArrivalStateFromUrl($expectedUrl))->toMatchArray([
        'sourceSurface' => PortfolioArrivalContextToken::SOURCE_TENANT_REGISTRY,
        'tenantRouteKey' => (string) $weakenedTenant->external_id,
        'workspaceId' => (int) $weakenedTenant->workspace_id,
        'concernFamily' => PortfolioArrivalContextToken::FAMILY_RECOVERY_EVIDENCE,
        'concernState' => TenantRecoveryTriagePresentation::RECOVERY_EVIDENCE_WEAKENED,
        'concernReason' => RestoreResultAttention::STATE_COMPLETED_WITH_FOLLOW_UP,
        'returnFilters' => [
            'backup_posture' => [TenantBackupHealthAssessment::POSTURE_STALE],
            'recovery_evidence' => [TenantRecoveryTriagePresentation::RECOVERY_EVIDENCE_WEAKENED],
            'triage_sort' => TenantRecoveryTriagePresentation::TRIAGE_SORT_WORST_FIRST,
        ],
    ]);
});

it('keeps generic registry opens free of arrival context when triage intent is not active', function (): void {
    [$user, $tenant] = $this->makePortfolioTriageActor('Generic Registry ManagedEnvironment');

    $expectedUrl = EnvironmentDashboard::getUrl(panel: 'admin', tenant: $tenant);

    $this->usePortfolioTriageWorkspace($user, $tenant);

    $this->portfolioTriageRegistryList($user, $tenant)
        ->assertTableActionHasUrl('openTenant', $expectedUrl, $tenant);

    expect($expectedUrl)->not->toContain(PortfolioArrivalContextToken::QUERY_PARAMETER.'=');
});

it('chooses the leading visible concern when worst-first triage is active without explicit family filters', function (): void {
    [$user, $anchorTenant] = $this->makePortfolioTriageActor('Worst First Anchor');
    $priorityTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Priority ManagedEnvironment');

    $this->seedPortfolioBackupConcern($priorityTenant, TenantBackupHealthAssessment::POSTURE_STALE);
    $this->seedPortfolioRecoveryConcern($priorityTenant, RestoreResultAttention::STATE_PARTIAL);

    $this->usePortfolioTriageWorkspace($user, $anchorTenant);

    $expectedUrl = ManagedEnvironmentResource::tenantDashboardOpenUrl($priorityTenant, [
        'triage_sort' => TenantRecoveryTriagePresentation::TRIAGE_SORT_WORST_FIRST,
    ]);

    $this->portfolioTriageRegistryList($user, $anchorTenant, [
        'triage_sort' => TenantRecoveryTriagePresentation::TRIAGE_SORT_WORST_FIRST,
    ])
        ->assertTableActionHasUrl('openTenant', $expectedUrl, $priorityTenant);

    expect(tenantRegistryArrivalStateFromUrl($expectedUrl))->toMatchArray([
        'sourceSurface' => PortfolioArrivalContextToken::SOURCE_TENANT_REGISTRY,
        'concernFamily' => PortfolioArrivalContextToken::FAMILY_RECOVERY_EVIDENCE,
        'concernState' => TenantRecoveryTriagePresentation::RECOVERY_EVIDENCE_WEAKENED,
        'concernReason' => RestoreResultAttention::STATE_PARTIAL,
    ]);
});
