<?php

declare(strict_types=1);

use App\Support\BackupHealth\TenantBackupHealthAssessment;
use App\Support\PortfolioTriage\PortfolioArrivalContextToken;
use App\Support\RestoreSafety\RestoreResultAttention;
use App\Support\Workspaces\WorkspaceOverviewBuilder;
use Tests\Feature\Concerns\BuildsPortfolioTriageFixtures;

uses(BuildsPortfolioTriageFixtures::class);

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

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

it('emits bounded arrival tokens for workspace backup and recovery attention drilldowns', function (): void {
    [$user, $backupTenant] = $this->makePortfolioTriageActor('Backup Weak ManagedEnvironment');
    $recoveryTenant = $this->makePortfolioTriagePeer($user, $backupTenant, 'Recovery Weak ManagedEnvironment');
    $this->seedPortfolioRecoveryConcern($recoveryTenant, RestoreResultAttention::STATE_COMPLETED_WITH_FOLLOW_UP);

    $workspace = $backupTenant->workspace()->firstOrFail();
    $items = collect(app(WorkspaceOverviewBuilder::class)->build($workspace, $user)['attention_items'])->keyBy('key');

    $backupArrivalState = workspaceOverviewArrivalStateFromUrl((string) $items->get('tenant_backup_absent')['destination']['url']);
    $recoveryArrivalState = workspaceOverviewArrivalStateFromUrl((string) $items->get('tenant_recovery_weakened')['destination']['url']);

    expect($backupArrivalState)->toMatchArray([
        'sourceSurface' => PortfolioArrivalContextToken::SOURCE_WORKSPACE_OVERVIEW,
        'tenantRouteKey' => (string) $backupTenant->external_id,
        'workspaceId' => (int) $backupTenant->workspace_id,
        'concernFamily' => PortfolioArrivalContextToken::FAMILY_BACKUP_HEALTH,
        'concernState' => TenantBackupHealthAssessment::POSTURE_ABSENT,
        'concernReason' => TenantBackupHealthAssessment::REASON_NO_BACKUP_BASIS,
    ])->and($recoveryArrivalState)->toMatchArray([
        'sourceSurface' => PortfolioArrivalContextToken::SOURCE_WORKSPACE_OVERVIEW,
        'tenantRouteKey' => (string) $recoveryTenant->external_id,
        'workspaceId' => (int) $recoveryTenant->workspace_id,
        'concernFamily' => PortfolioArrivalContextToken::FAMILY_RECOVERY_EVIDENCE,
        'concernState' => 'weakened',
        'concernReason' => RestoreResultAttention::STATE_COMPLETED_WITH_FOLLOW_UP,
    ]);
});

it('emits summary-metric arrival tokens only when the workspace drilldown lands on a single tenant dashboard', function (): void {
    [$user, $backupTenant] = $this->makePortfolioTriageActor('Single Backup ManagedEnvironment');

    $recoveryTenantA = $this->makePortfolioTriagePeer($user, $backupTenant, 'Recovery ManagedEnvironment A');
    $this->seedPortfolioRecoveryConcern($recoveryTenantA, RestoreResultAttention::STATE_FAILED);

    $recoveryTenantB = $this->makePortfolioTriagePeer($user, $backupTenant, 'Recovery ManagedEnvironment B');
    $this->seedPortfolioRecoveryConcern($recoveryTenantB, RestoreResultAttention::STATE_PARTIAL);

    $workspace = $backupTenant->workspace()->firstOrFail();
    $metrics = collect(app(WorkspaceOverviewBuilder::class)->build($workspace, $user)['summary_metrics'])->keyBy('key');

    $backupDestinationUrl = (string) $metrics->get('backup_attention_tenants')['destination_url'];
    $recoveryDestinationUrl = (string) $metrics->get('recovery_attention_tenants')['destination_url'];

    $backupArrivalState = workspaceOverviewArrivalStateFromUrl($backupDestinationUrl);

    expect($backupArrivalState)->toMatchArray([
        'sourceSurface' => PortfolioArrivalContextToken::SOURCE_WORKSPACE_OVERVIEW,
        'tenantRouteKey' => (string) $backupTenant->external_id,
        'concernFamily' => PortfolioArrivalContextToken::FAMILY_BACKUP_HEALTH,
        'concernState' => TenantBackupHealthAssessment::POSTURE_ABSENT,
    ])->and($recoveryDestinationUrl)->toContain('/admin/workspaces/')
        ->and($recoveryDestinationUrl)->toContain('/environments')
        ->and($recoveryDestinationUrl)->not->toContain(PortfolioArrivalContextToken::QUERY_PARAMETER.'=');
});
