<?php

declare(strict_types=1);

namespace App\Support\Tenants;

use App\Support\BackupHealth\TenantBackupHealthAssessment;
use App\Support\RestoreSafety\RestoreResultAttention;
use Illuminate\Support\Str;

final class TenantRecoveryTriagePresentation
{
    public const RECOVERY_EVIDENCE_WEAKENED = 'weakened';

    public const RECOVERY_EVIDENCE_UNVALIDATED = 'unvalidated';

    public const RECOVERY_EVIDENCE_NO_RECENT_ISSUES_VISIBLE = 'no_recent_issues_visible';

    public const TRIAGE_SORT_DEFAULT = 'default';

    public const TRIAGE_SORT_WORST_FIRST = 'worst_first';

    /**
     * @return array<string, string>
     */
    public static function backupPostureOptions(): array
    {
        return [
            TenantBackupHealthAssessment::POSTURE_ABSENT => 'Absent',
            TenantBackupHealthAssessment::POSTURE_STALE => 'Stale',
            TenantBackupHealthAssessment::POSTURE_DEGRADED => 'Degraded',
            TenantBackupHealthAssessment::POSTURE_HEALTHY => 'Healthy',
        ];
    }

    /**
     * @return array<string, string>
     */
    public static function recoveryEvidenceOptions(): array
    {
        return [
            self::RECOVERY_EVIDENCE_WEAKENED => 'Weakened',
            self::RECOVERY_EVIDENCE_UNVALIDATED => 'Unvalidated',
            self::RECOVERY_EVIDENCE_NO_RECENT_ISSUES_VISIBLE => 'No recent issues visible',
        ];
    }

    /**
     * @return array<string, string>
     */
    public static function triageSortOptions(): array
    {
        return [
            self::TRIAGE_SORT_DEFAULT => 'Default order',
            self::TRIAGE_SORT_WORST_FIRST => 'Worst first',
        ];
    }

    public static function backupPostureState(?TenantBackupHealthAssessment $assessment): ?string
    {
        return $assessment?->posture;
    }

    public static function backupPostureLabel(?TenantBackupHealthAssessment $assessment): string
    {
        $state = self::backupPostureState($assessment);

        if ($state === null) {
            return 'Unknown';
        }

        return self::backupPostureOptions()[$state] ?? Str::headline($state);
    }

    public static function backupPostureTone(?TenantBackupHealthAssessment $assessment): string
    {
        return $assessment?->tone() ?? 'gray';
    }

    public static function backupPostureDescription(?TenantBackupHealthAssessment $assessment, ?string $helperText = null): ?string
    {
        if (! $assessment instanceof TenantBackupHealthAssessment) {
            return $helperText;
        }

        $parts = [
            $assessment->supportingMessage ?? $assessment->headline,
            $assessment->posture === TenantBackupHealthAssessment::POSTURE_HEALTHY
                ? $assessment->positiveClaimBoundary
                : null,
            $helperText,
        ];

        $description = trim(implode(' ', array_filter($parts, static fn (?string $part): bool => filled($part))));

        return $description !== '' ? $description : null;
    }

    /**
     * @param  array<string, mixed>|null  $recoveryEvidence
     */
    public static function recoveryEvidenceState(?array $recoveryEvidence): ?string
    {
        $state = $recoveryEvidence['overview_state'] ?? null;

        return is_string($state) && $state !== '' ? $state : null;
    }

    /**
     * @param  array<string, mixed>|null  $recoveryEvidence
     */
    public static function recoveryEvidenceLabel(?array $recoveryEvidence): string
    {
        $state = self::recoveryEvidenceState($recoveryEvidence);

        if ($state === null) {
            return 'Unknown';
        }

        return self::recoveryEvidenceOptions()[$state] ?? Str::headline($state);
    }

    /**
     * @param  array<string, mixed>|null  $recoveryEvidence
     */
    public static function recoveryEvidenceDescription(?array $recoveryEvidence, ?string $helperText = null): ?string
    {
        if (! is_array($recoveryEvidence)) {
            return $helperText;
        }

        $parts = [
            is_string($recoveryEvidence['summary'] ?? null) ? $recoveryEvidence['summary'] : null,
            is_string($recoveryEvidence['claim_boundary'] ?? null) ? $recoveryEvidence['claim_boundary'] : null,
            $helperText,
        ];

        $description = trim(implode(' ', array_filter($parts, static fn (?string $part): bool => filled($part))));

        return $description !== '' ? $description : null;
    }

    /**
     * @param  array<string, mixed>|null  $recoveryEvidence
     */
    public static function recoveryEvidenceTone(?array $recoveryEvidence): string
    {
        if (! is_array($recoveryEvidence)) {
            return 'gray';
        }

        $attentionState = is_string($recoveryEvidence['latest_relevant_attention_state'] ?? null)
            ? $recoveryEvidence['latest_relevant_attention_state']
            : null;

        return match (self::recoveryEvidenceState($recoveryEvidence)) {
            self::RECOVERY_EVIDENCE_UNVALIDATED => 'warning',
            self::RECOVERY_EVIDENCE_WEAKENED => $attentionState === RestoreResultAttention::STATE_FAILED ? 'danger' : 'warning',
            self::RECOVERY_EVIDENCE_NO_RECENT_ISSUES_VISIBLE => 'success',
            default => 'gray',
        };
    }

    /**
     * @param  array<string, mixed>|null  $recoveryEvidence
     */
    public static function triageTier(
        ?TenantBackupHealthAssessment $backupHealth,
        ?array $recoveryEvidence,
    ): int {
        $backupPosture = self::backupPostureState($backupHealth);
        $recoveryState = self::recoveryEvidenceState($recoveryEvidence);

        return match (true) {
            $backupPosture === TenantBackupHealthAssessment::POSTURE_ABSENT => 1,
            $recoveryState === self::RECOVERY_EVIDENCE_WEAKENED => 2,
            $backupPosture === TenantBackupHealthAssessment::POSTURE_STALE => 3,
            $recoveryState === self::RECOVERY_EVIDENCE_UNVALIDATED => 4,
            $backupPosture === TenantBackupHealthAssessment::POSTURE_DEGRADED => 5,
            default => 6,
        };
    }
}
