<?php

declare(strict_types=1);

namespace App\Support\SupportDiagnostics;

use App\Filament\Resources\EnvironmentReviewResource;
use App\Filament\Resources\FindingResource;
use App\Filament\Resources\ProviderConnectionResource;
use App\Filament\Resources\ReviewPackResource;
use App\Models\AuditLog;
use App\Models\EnvironmentReview;
use App\Models\Finding;
use App\Models\ManagedEnvironment;
use App\Models\OperationRun;
use App\Models\ProviderConnection;
use App\Models\ReviewPack;
use App\Models\StoredReport;
use App\Models\User;
use App\Models\Workspace;
use App\Support\Ai\AiDataClassification;
use App\Support\ManagedEnvironmentLinks;
use App\Support\Navigation\RelatedNavigationResolver;
use App\Support\OperationRunLinks;
use App\Support\OpsUx\GovernanceRunDiagnosticSummaryBuilder;
use App\Support\ProductKnowledge\ContextualHelpResolver;
use App\Support\Providers\ProviderReasonTranslator;
use App\Support\Providers\TargetScope\ProviderConnectionSurfaceSummary;
use App\Support\RedactionIntegrity;
use Carbon\CarbonInterface;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;

final class SupportDiagnosticBundleBuilder
{
    private const SECTION_ORDER = [
        'overview',
        'provider_connection',
        'operation_context',
        'findings',
        'stored_reports',
        'environment_review',
        'review_pack',
        'audit_history',
    ];

    public function __construct(
        private readonly GovernanceRunDiagnosticSummaryBuilder $runSummaryBuilder,
        private readonly ProviderReasonTranslator $providerReasonTranslator,
        private readonly RelatedNavigationResolver $relatedNavigationResolver,
        private readonly ContextualHelpResolver $contextualHelpResolver,
    ) {}

    /**
     * @return array<string, mixed>
     */
    public function forTenant(ManagedEnvironment $tenant, ?User $actor = null): array
    {
        $tenant->loadMissing('workspace');

        $workspace = $tenant->workspace;
        $providerConnection = $this->tenantProviderConnection($tenant);
        $operationRun = $this->tenantOperationRun($tenant);
        $findings = $this->tenantFindings($tenant);
        $storedReports = $this->tenantStoredReports($tenant);
        $environmentReview = $this->environmentReview($tenant);
        $reviewPack = $this->environmentReviewPack($tenant, $environmentReview);
        $auditLogs = $this->tenantAuditLogs($tenant);

        return $this->bundle(
            contextType: 'tenant',
            workspace: $workspace,
            tenant: $tenant,
            providerConnection: $providerConnection,
            operationRun: $operationRun,
            headline: 'Support diagnostics for '.$tenant->name,
            dominantIssue: $this->tenantDominantIssue($providerConnection, $operationRun, $findings),
            sections: [
                $this->overviewSection($workspace, $tenant, $operationRun),
                $this->providerConnectionSection($providerConnection, $tenant),
                $this->operationContextSection($operationRun, $tenant),
                $this->findingsSection($findings, $tenant),
                $this->storedReportsSection($storedReports),
                $this->environmentReviewSection($environmentReview, $tenant),
                $this->reviewPackSection($reviewPack, $tenant),
                $this->auditHistorySection($auditLogs),
            ],
        );
    }

    /**
     * @return array<string, mixed>
     */
    public function forOperationRun(OperationRun $run, ?User $actor = null): array
    {
        $run->loadMissing(['workspace', 'tenant']);

        $workspace = $run->workspace;
        $tenant = $run->tenant;
        $providerConnection = $tenant instanceof ManagedEnvironment
            ? $this->operationProviderConnection($run, $tenant)
            : null;
        $findings = $tenant instanceof ManagedEnvironment ? $this->operationFindings($run, $tenant) : collect();
        $storedReports = $tenant instanceof ManagedEnvironment ? $this->tenantStoredReports($tenant) : collect();
        $environmentReview = $tenant instanceof ManagedEnvironment ? $this->operationEnvironmentReview($run, $tenant) : null;
        $reviewPack = $tenant instanceof ManagedEnvironment ? $this->operationReviewPack($run, $tenant, $environmentReview) : null;
        $auditLogs = $this->operationAuditLogs($run);
        $runSummary = $this->runSummaryBuilder->build($run);
        $runSummaryArray = $runSummary?->toArray();

        return $this->bundle(
            contextType: 'operation_run',
            workspace: $workspace,
            tenant: $tenant,
            providerConnection: $providerConnection,
            operationRun: $run,
            headline: $runSummaryArray['headline'] ?? OperationRunLinks::identifier($run).' support diagnostics',
            dominantIssue: (string) data_get(
                $runSummaryArray,
                'dominantCause.explanation',
                $this->operationDominantIssue($run),
            ),
            sections: [
                $this->overviewSection($workspace, $tenant, $run),
                $this->providerConnectionSection($providerConnection, $tenant, $run),
                $this->operationContextSection($run, $tenant, $runSummaryArray),
                $this->findingsSection($findings, $tenant),
                $this->storedReportsSection($storedReports),
                $this->environmentReviewSection($environmentReview, $tenant),
                $this->reviewPackSection($reviewPack, $tenant),
                $this->auditHistorySection($auditLogs),
            ],
        );
    }

    /**
     * @return array{
     *     use_case_key: string,
     *     source_family: string,
     *     data_classifications: list<string>,
     *     summary: array{
     *         headline: string,
     *         dominant_issue: string,
     *         freshness_state: string,
     *         completeness_note: ?string,
     *         redaction_note: string,
     *         generated_from: string
     *     },
     *     redaction: array{mode: string, markers: list<string>},
     *     notes: list<string>
     * }
     */
    public function aiSupportDiagnosticsSummaryDraftSource(ManagedEnvironment $tenant, ?User $actor = null): array
    {
        $bundle = $this->forTenant($tenant, $actor);

        return [
            'use_case_key' => 'support_diagnostics.summary_draft',
            'source_family' => 'support_diagnostics',
            'data_classifications' => [
                AiDataClassification::RedactedSupportSummary->value,
            ],
            'summary' => $bundle['summary'],
            'redaction' => $bundle['redaction'],
            'notes' => $bundle['notes'],
        ];
    }

    /**
     * @param  list<array<string, mixed>>  $sections
     * @return array<string, mixed>
     */
    private function bundle(
        string $contextType,
        ?Workspace $workspace,
        ?ManagedEnvironment $tenant,
        ?ProviderConnection $providerConnection,
        ?OperationRun $operationRun,
        string $headline,
        string $dominantIssue,
        array $sections,
    ): array {
        $sections = $this->sortSections($sections);
        $redactionMarkers = RedactionIntegrity::supportDiagnosticsMarkers();
        $contextualHelp = $this->contextualHelp($tenant, $providerConnection, $operationRun, $sections);

        return [
            'context_type' => $contextType,
            'context' => [
                'type' => $contextType,
                'workspace_id' => $workspace instanceof Workspace ? (int) $workspace->getKey() : null,
                'managed_environment_id' => $tenant instanceof ManagedEnvironment ? (int) $tenant->getKey() : null,
                'operation_run_id' => $operationRun instanceof OperationRun ? (int) $operationRun->getKey() : null,
                'tenant_label' => $tenant?->name,
                'workspace_label' => $workspace?->name,
            ],
            'workspace' => $workspace instanceof Workspace ? [
                'record_id' => (string) $workspace->getKey(),
                'label' => $workspace->name,
            ] : null,
            'tenant' => $tenant instanceof ManagedEnvironment ? $this->tenantReference($tenant) : null,
            'operation_run' => $operationRun instanceof OperationRun ? $this->operationReference($operationRun, $tenant) : null,
            'headline' => $headline,
            'dominant_issue' => $dominantIssue,
            'freshness_state' => $this->freshnessState($sections),
            'redaction_mode' => 'default_redacted',
            'summary' => [
                'headline' => $headline,
                'dominant_issue' => $dominantIssue,
                'freshness_state' => $this->freshnessState($sections),
                'completeness_note' => $this->completenessNote($sections),
                'redaction_note' => RedactionIntegrity::supportDiagnosticsNote(),
                'generated_from' => 'derived_existing_truth',
            ],
            'contextual_help' => $contextualHelp,
            'sections' => $sections,
            'redaction' => [
                'mode' => 'default_redacted',
                'markers' => $redactionMarkers,
            ],
            'notes' => array_values(array_filter([
                RedactionIntegrity::supportDiagnosticsNote(),
                $this->completenessNote($sections),
            ])),
        ];
    }

    /**
     * @param  list<array<string, mixed>>  $sections
     * @return array<string, mixed>|null
     */
    private function contextualHelp(
        ?ManagedEnvironment $tenant,
        ?ProviderConnection $providerConnection,
        ?OperationRun $operationRun,
        array $sections,
    ): ?array {
        if (! $tenant instanceof ManagedEnvironment) {
            return null;
        }

        $reasonCode = $this->supportDiagnosticReasonCode($providerConnection, $operationRun);
        $topicKey = $this->contextualHelpResolver->topicKeyForSupportDiagnostics(
            reasonCode: $reasonCode,
            hasIncompleteEvidence: $this->completenessNote($sections) !== null,
            runOutcome: $operationRun instanceof OperationRun && is_string($operationRun->outcome)
                ? (string) $operationRun->outcome
                : null,
        );

        if ($topicKey === null) {
            return null;
        }

        return $this->contextualHelpResolver->tryResolve($topicKey, [
            'tenant' => $tenant,
            'connection' => $providerConnection,
            'reason_code' => $reasonCode,
            'surface' => 'support_diagnostics',
        ]);
    }

    private function supportDiagnosticReasonCode(?ProviderConnection $providerConnection, ?OperationRun $operationRun): ?string
    {
        $providerReasonCode = is_string($providerConnection?->last_error_reason_code)
            ? trim((string) $providerConnection->last_error_reason_code)
            : '';

        if ($providerReasonCode !== '') {
            return $providerReasonCode;
        }

        $failureReasonCode = data_get($operationRun?->failure_summary, '0.reason_code');

        if (is_string($failureReasonCode) && trim($failureReasonCode) !== '') {
            return trim($failureReasonCode);
        }

        return null;
    }

    private function tenantProviderConnection(ManagedEnvironment $tenant): ?ProviderConnection
    {
        return ProviderConnection::query()
            ->where('managed_environment_id', (int) $tenant->getKey())
            ->where('workspace_id', (int) $tenant->workspace_id)
            ->orderByDesc('is_default')
            ->orderByDesc('last_health_check_at')
            ->orderByDesc('id')
            ->first();
    }

    private function operationProviderConnection(OperationRun $run, ManagedEnvironment $tenant): ?ProviderConnection
    {
        $context = is_array($run->context) ? $run->context : [];
        $providerConnectionId = data_get($context, 'provider_connection_id');

        if (is_numeric($providerConnectionId)) {
            $connection = ProviderConnection::query()
                ->whereKey((int) $providerConnectionId)
                ->where('workspace_id', (int) $tenant->workspace_id)
                ->where('managed_environment_id', (int) $tenant->getKey())
                ->first();

            if ($connection instanceof ProviderConnection) {
                return $connection;
            }
        }

        return $this->tenantProviderConnection($tenant);
    }

    private function tenantOperationRun(ManagedEnvironment $tenant): ?OperationRun
    {
        return OperationRun::query()
            ->where('managed_environment_id', (int) $tenant->getKey())
            ->where('workspace_id', (int) $tenant->workspace_id)
            ->orderByRaw('completed_at IS NULL')
            ->orderByDesc('completed_at')
            ->orderByDesc('created_at')
            ->orderByDesc('id')
            ->first();
    }

    /**
     * @return Collection<int, Finding>
     */
    private function tenantFindings(ManagedEnvironment $tenant): Collection
    {
        return Finding::query()
            ->where('managed_environment_id', (int) $tenant->getKey())
            ->where('workspace_id', (int) $tenant->workspace_id)
            ->whereIn('status', Finding::openStatusesForQuery())
            ->orderByRaw("CASE severity WHEN 'critical' THEN 0 WHEN 'high' THEN 1 WHEN 'medium' THEN 2 WHEN 'low' THEN 3 ELSE 4 END")
            ->orderByDesc('last_seen_at')
            ->orderBy('id')
            ->limit(3)
            ->get();
    }

    /**
     * @return Collection<int, Finding>
     */
    private function operationFindings(OperationRun $run, ManagedEnvironment $tenant): Collection
    {
        $runBound = Finding::query()
            ->where('managed_environment_id', (int) $tenant->getKey())
            ->where('workspace_id', (int) $tenant->workspace_id)
            ->where(function (Builder $query) use ($run): void {
                $query
                    ->where('current_operation_run_id', (int) $run->getKey())
                    ->orWhere('baseline_operation_run_id', (int) $run->getKey());
            })
            ->orderByRaw("CASE severity WHEN 'critical' THEN 0 WHEN 'high' THEN 1 WHEN 'medium' THEN 2 WHEN 'low' THEN 3 ELSE 4 END")
            ->orderByDesc('last_seen_at')
            ->orderBy('id')
            ->limit(3)
            ->get();

        return $runBound->isNotEmpty() ? $runBound : $this->tenantFindings($tenant);
    }

    /**
     * @return Collection<int, StoredReport>
     */
    private function tenantStoredReports(ManagedEnvironment $tenant): Collection
    {
        return StoredReport::query()
            ->where('managed_environment_id', (int) $tenant->getKey())
            ->where('workspace_id', (int) $tenant->workspace_id)
            ->orderByDesc('updated_at')
            ->orderByDesc('id')
            ->limit(3)
            ->get();
    }

    private function environmentReview(ManagedEnvironment $tenant): ?EnvironmentReview
    {
        return EnvironmentReview::query()
            ->where('managed_environment_id', (int) $tenant->getKey())
            ->where('workspace_id', (int) $tenant->workspace_id)
            ->orderByDesc('generated_at')
            ->orderByDesc('id')
            ->first();
    }

    private function operationEnvironmentReview(OperationRun $run, ManagedEnvironment $tenant): ?EnvironmentReview
    {
        $review = EnvironmentReview::query()
            ->where('managed_environment_id', (int) $tenant->getKey())
            ->where('workspace_id', (int) $tenant->workspace_id)
            ->where('operation_run_id', (int) $run->getKey())
            ->orderByDesc('generated_at')
            ->orderByDesc('id')
            ->first();

        return $review instanceof EnvironmentReview ? $review : $this->environmentReview($tenant);
    }

    private function environmentReviewPack(ManagedEnvironment $tenant, ?EnvironmentReview $environmentReview): ?ReviewPack
    {
        if ($environmentReview instanceof EnvironmentReview && is_numeric($environmentReview->current_export_review_pack_id)) {
            $pack = ReviewPack::query()
                ->whereKey((int) $environmentReview->current_export_review_pack_id)
                ->where('managed_environment_id', (int) $tenant->getKey())
                ->where('workspace_id', (int) $tenant->workspace_id)
                ->first();

            if ($pack instanceof ReviewPack) {
                return $pack;
            }
        }

        return ReviewPack::query()
            ->where('managed_environment_id', (int) $tenant->getKey())
            ->where('workspace_id', (int) $tenant->workspace_id)
            ->orderByDesc('generated_at')
            ->orderByDesc('id')
            ->first();
    }

    private function operationReviewPack(OperationRun $run, ManagedEnvironment $tenant, ?EnvironmentReview $environmentReview): ?ReviewPack
    {
        $pack = ReviewPack::query()
            ->where('managed_environment_id', (int) $tenant->getKey())
            ->where('workspace_id', (int) $tenant->workspace_id)
            ->where('operation_run_id', (int) $run->getKey())
            ->orderByDesc('generated_at')
            ->orderByDesc('id')
            ->first();

        return $pack instanceof ReviewPack ? $pack : $this->environmentReviewPack($tenant, $environmentReview);
    }

    /**
     * @return Collection<int, AuditLog>
     */
    private function tenantAuditLogs(ManagedEnvironment $tenant): Collection
    {
        return AuditLog::query()
            ->where('managed_environment_id', (int) $tenant->getKey())
            ->where('workspace_id', (int) $tenant->workspace_id)
            ->latestFirst()
            ->limit(5)
            ->get();
    }

    /**
     * @return Collection<int, AuditLog>
     */
    private function operationAuditLogs(OperationRun $run): Collection
    {
        return AuditLog::query()
            ->where('workspace_id', (int) $run->workspace_id)
            ->where(function (Builder $query) use ($run): void {
                $query
                    ->where('operation_run_id', (int) $run->getKey())
                    ->orWhere(function (Builder $targetQuery) use ($run): void {
                        $targetQuery
                            ->where('resource_type', 'operation_run')
                            ->where('resource_id', (string) $run->getKey());
                    });
            })
            ->latestFirst()
            ->limit(5)
            ->get();
    }

    private function tenantDominantIssue(?ProviderConnection $providerConnection, ?OperationRun $operationRun, Collection $findings): string
    {
        if ($providerConnection instanceof ProviderConnection) {
            $providerIssue = $this->providerIssue($providerConnection);

            if ($providerIssue !== null) {
                return $providerIssue;
            }
        }

        if ($operationRun instanceof OperationRun && in_array((string) $operationRun->outcome, ['failed', 'blocked', 'partially_succeeded'], true)) {
            return $this->operationDominantIssue($operationRun);
        }

        if ($findings->isNotEmpty()) {
            return 'Open findings need review before support can treat this tenant as quiet.';
        }

        return 'No dominant support blocker is currently visible from the selected tenant context.';
    }

    private function operationDominantIssue(OperationRun $run): string
    {
        $failure = collect(is_array($run->failure_summary) ? $run->failure_summary : [])
            ->first(static fn (mixed $item): bool => is_array($item) && trim((string) ($item['message'] ?? '')) !== '');

        if (is_array($failure)) {
            return trim((string) $failure['message']);
        }

        return match ((string) $run->outcome) {
            'failed' => 'The operation failed and needs follow-up.',
            'blocked' => 'The operation was blocked by a prerequisite or policy condition.',
            'partially_succeeded' => 'The operation completed with degraded or partial results.',
            default => 'The operation is available for support review.',
        };
    }

    private function providerIssue(ProviderConnection $connection): ?string
    {
        $reasonCode = trim((string) $connection->last_error_reason_code);

        if ($reasonCode !== '') {
            $envelope = $this->providerReasonTranslator->translate($reasonCode, 'support_diagnostics', [
                'tenant' => $connection->tenant,
                'connection' => $connection,
            ]);

            if ($envelope !== null) {
                return $envelope->operatorLabel.': '.$envelope->shortExplanation;
            }
        }

        $surface = ProviderConnectionSurfaceSummary::forConnection($connection);

        if ($surface->readinessSummary !== 'Ready') {
            return 'Provider connection '.$surface->readinessSummary.'.';
        }

        return null;
    }

    private function overviewSection(?Workspace $workspace, ?ManagedEnvironment $tenant, ?OperationRun $operationRun): array
    {
        $references = array_values(array_filter([
            $tenant instanceof ManagedEnvironment ? $this->tenantReference($tenant) : null,
            $operationRun instanceof OperationRun ? $this->operationReference($operationRun, $tenant) : null,
        ]));

        return $this->section(
            key: 'overview',
            label: 'Overview',
            availability: $references === [] ? 'missing' : 'available',
            summary: $tenant instanceof ManagedEnvironment
                ? 'Workspace and tenant scope resolved before support diagnostics were composed.'
                : 'Workspace scope resolved; no tenant context is attached to this operation.',
            references: $references,
        );
    }

    private function providerConnectionSection(?ProviderConnection $connection, ?ManagedEnvironment $tenant, ?OperationRun $run = null): array
    {
        if (! $connection instanceof ProviderConnection) {
            return $this->section(
                key: 'provider_connection',
                label: 'Provider connection',
                availability: 'missing',
                summary: 'No provider connection was found for this support context.',
                references: [
                    $this->missingReference('provider_connection', 'Provider connection not observed', 'Open provider connection'),
                ],
                redactionMarkers: [
                    [
                        'path' => 'provider_connection.credential',
                        'reason' => 'credential',
                        'replacement_text' => '[REDACTED]',
                    ],
                ],
            );
        }

        $surface = ProviderConnectionSurfaceSummary::forConnection($connection);
        $providerIssue = $this->providerIssue($connection);

        return $this->section(
            key: 'provider_connection',
            label: 'Provider connection',
            availability: $surface->readinessSummary === 'Ready' ? 'available' : 'stale',
            summary: $providerIssue ?? sprintf(
                '%s provider connection is %s.',
                ucfirst($surface->provider),
                strtolower($surface->readinessSummary),
            ),
            freshnessNote: $this->freshnessNote($connection->last_health_check_at, 'Last health check'),
            references: [
                $this->modelReference(
                    type: 'provider_connection',
                    record: $connection,
                    label: $connection->display_name ?: 'Provider connection #'.$connection->getKey(),
                    actionLabel: 'Open provider connection',
                    url: ProviderConnectionResource::getUrl('view', ['record' => $connection], panel: 'admin'),
                    freshnessAt: $connection->last_health_check_at,
                ),
            ],
            redactionMarkers: [
                [
                    'path' => 'provider_connection.credential',
                    'reason' => 'credential',
                    'replacement_text' => '[REDACTED]',
                ],
            ],
        );
    }

    private function operationContextSection(?OperationRun $operationRun, ?ManagedEnvironment $tenant, ?array $runSummary = null): array
    {
        if (! $operationRun instanceof OperationRun) {
            return $this->section(
                key: 'operation_context',
                label: 'Operation context',
                availability: 'missing',
                summary: 'No recent operation context was found for this support context.',
                references: [
                    $this->missingReference('operation_run', 'Operation not yet observed', OperationRunLinks::openLabel()),
                ],
            );
        }

        $runSummary ??= $this->runSummaryBuilder->build($operationRun)?->toArray();

        return $this->section(
            key: 'operation_context',
            label: 'Operation context',
            availability: 'available',
            summary: (string) ($runSummary['headline'] ?? $this->operationDominantIssue($operationRun)),
            freshnessNote: $this->freshnessNote($operationRun->completed_at ?? $operationRun->updated_at, 'Last run update'),
            references: [
                $this->operationReference($operationRun, $tenant),
                ...$this->operationRelatedReferences($operationRun, $tenant),
            ],
        );
    }

    private function findingsSection(Collection $findings, ?ManagedEnvironment $tenant): array
    {
        if ($findings->isEmpty()) {
            return $this->section(
                key: 'findings',
                label: 'Findings',
                availability: 'missing',
                summary: 'No open or run-related findings were found for this support context.',
                references: [
                    $this->missingReference('finding', 'No relevant finding observed', 'Open finding'),
                ],
            );
        }

        return $this->section(
            key: 'findings',
            label: 'Findings',
            availability: 'available',
            summary: sprintf('%d finding reference(s) are included for support triage.', $findings->count()),
            freshnessNote: $this->freshnessNote($findings->max('last_seen_at'), 'Latest finding'),
            references: $findings
                ->map(fn (Finding $finding): array => $this->modelReference(
                    type: 'finding',
                    record: $finding,
                    label: sprintf('%s finding #%d', ucfirst(str_replace('_', ' ', (string) $finding->severity)), (int) $finding->getKey()),
                    actionLabel: 'Open finding',
                    url: $tenant instanceof ManagedEnvironment
                        ? FindingResource::getUrl('view', ['record' => $finding], tenant: $tenant)
                        : null,
                    freshnessAt: $finding->last_seen_at,
                ))
                ->values()
                ->all(),
        );
    }

    private function storedReportsSection(Collection $reports): array
    {
        if ($reports->isEmpty()) {
            return $this->section(
                key: 'stored_reports',
                label: 'Stored reports',
                availability: 'missing',
                summary: 'No stored report identity was found for this support context.',
                references: [
                    $this->missingReference('stored_report', 'Stored report not yet observed', 'Review stored report identity'),
                ],
                redactionMarkers: [
                    [
                        'path' => 'stored_reports.payload',
                        'reason' => 'raw_payload',
                        'replacement_text' => '[REDACTED]',
                    ],
                ],
            );
        }

        return $this->section(
            key: 'stored_reports',
            label: 'Stored reports',
            availability: 'redacted',
            summary: sprintf('%d stored report identity reference(s) are included without raw report payloads.', $reports->count()),
            freshnessNote: $this->freshnessNote($reports->max('updated_at'), 'Latest stored report'),
            references: $reports
                ->map(fn (StoredReport $report): array => $this->modelReference(
                    type: 'stored_report',
                    record: $report,
                    label: str_replace('_', ' ', (string) $report->report_type).' report #'.$report->getKey(),
                    actionLabel: 'Review stored report identity',
                    url: null,
                    freshnessAt: $report->updated_at,
                ))
                ->values()
                ->all(),
            redactionMarkers: [
                [
                    'path' => 'stored_reports.payload',
                    'reason' => 'raw_payload',
                    'replacement_text' => '[REDACTED]',
                ],
            ],
        );
    }

    private function environmentReviewSection(?EnvironmentReview $review, ?ManagedEnvironment $tenant): array
    {
        if (! $review instanceof EnvironmentReview) {
            return $this->section(
                key: 'environment_review',
                label: 'ManagedEnvironment review',
                availability: 'missing',
                summary: 'No environment review was found for this support context.',
                references: [
                    $this->missingReference('environment_review', 'ManagedEnvironment review not yet observed', 'Open environment review'),
                ],
            );
        }

        return $this->section(
            key: 'environment_review',
            label: 'ManagedEnvironment review',
            availability: 'available',
            summary: sprintf('Latest environment review is %s with %s completeness.', (string) $review->status, (string) $review->completeness_state),
            freshnessNote: $this->freshnessNote($review->generated_at, 'Generated'),
            references: [
                $this->modelReference(
                    type: 'environment_review',
                    record: $review,
                    label: 'ManagedEnvironment review #'.$review->getKey(),
                    actionLabel: 'Open environment review',
                    url: $tenant instanceof ManagedEnvironment
                        ? EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review], $tenant)
                        : null,
                    freshnessAt: $review->generated_at,
                ),
            ],
        );
    }

    private function reviewPackSection(?ReviewPack $pack, ?ManagedEnvironment $tenant): array
    {
        if (! $pack instanceof ReviewPack) {
            return $this->section(
                key: 'review_pack',
                label: 'Review pack',
                availability: 'missing',
                summary: 'No review pack was found for this support context.',
                references: [
                    $this->missingReference('review_pack', 'Review pack not yet observed', 'Open review pack'),
                ],
            );
        }

        return $this->section(
            key: 'review_pack',
            label: 'Review pack',
            availability: $pack->isExpired() ? 'stale' : 'available',
            summary: sprintf('Review pack #%d is %s.', (int) $pack->getKey(), (string) $pack->status),
            freshnessNote: $this->freshnessNote($pack->generated_at, 'Generated'),
            references: [
                $this->modelReference(
                    type: 'review_pack',
                    record: $pack,
                    label: 'Review pack #'.$pack->getKey(),
                    actionLabel: 'Open review pack',
                    url: $tenant instanceof ManagedEnvironment
                        ? ReviewPackResource::getUrl('view', ['record' => $pack], tenant: $tenant)
                        : null,
                    freshnessAt: $pack->generated_at,
                ),
            ],
        );
    }

    private function auditHistorySection(Collection $auditLogs): array
    {
        if ($auditLogs->isEmpty()) {
            return $this->section(
                key: 'audit_history',
                label: 'Audit history',
                availability: 'missing',
                summary: 'No audit references were found for this support context.',
                references: [
                    $this->missingReference('audit_log', 'Audit event not yet observed', 'Inspect event'),
                ],
                redactionMarkers: [
                    [
                        'path' => 'audit_logs.metadata.raw',
                        'reason' => 'restricted_log_excerpt',
                        'replacement_text' => '[REDACTED]',
                    ],
                ],
            );
        }

        return $this->section(
            key: 'audit_history',
            label: 'Audit history',
            availability: 'redacted',
            summary: sprintf('%d audit reference(s) are included with redacted metadata only.', $auditLogs->count()),
            freshnessNote: $this->freshnessNote($auditLogs->max('recorded_at'), 'Latest audit event'),
            references: $auditLogs
                ->map(fn (AuditLog $auditLog): array => $this->modelReference(
                    type: 'audit_log',
                    record: $auditLog,
                    label: $auditLog->summaryText(),
                    actionLabel: 'Inspect event',
                    url: route('admin.monitoring.audit-log', ['event' => (int) $auditLog->getKey()]),
                    freshnessAt: $auditLog->recorded_at,
                ))
                ->values()
                ->all(),
            redactionMarkers: [
                [
                    'path' => 'audit_logs.metadata.raw',
                    'reason' => 'restricted_log_excerpt',
                    'replacement_text' => '[REDACTED]',
                ],
            ],
        );
    }

    /**
     * @param  list<array<string, mixed>>  $references
     * @param  list<array{path: ?string, reason: string, replacement_text: string}>  $redactionMarkers
     * @return array<string, mixed>
     */
    private function section(
        string $key,
        string $label,
        string $availability,
        string $summary,
        ?string $freshnessNote = null,
        array $references = [],
        array $redactionMarkers = [],
    ): array {
        return [
            'key' => $key,
            'label' => $label,
            'availability' => $availability,
            'summary' => $summary,
            'freshness_note' => $freshnessNote,
            'references' => $this->sortReferences($references),
            'redaction_markers' => $redactionMarkers,
        ];
    }

    /**
     * @param  list<array<string, mixed>>  $sections
     * @return list<array<string, mixed>>
     */
    private function sortSections(array $sections): array
    {
        $order = array_flip(self::SECTION_ORDER);

        usort($sections, static fn (array $left, array $right): int => ($order[$left['key']] ?? 999) <=> ($order[$right['key']] ?? 999));

        return array_values($sections);
    }

    /**
     * @param  list<array<string, mixed>>  $references
     * @return list<array<string, mixed>>
     */
    private function sortReferences(array $references): array
    {
        usort($references, function (array $left, array $right): int {
            $leftAvailability = $left['availability'] === 'available' ? 0 : 1;
            $rightAvailability = $right['availability'] === 'available' ? 0 : 1;

            if ($leftAvailability !== $rightAvailability) {
                return $leftAvailability <=> $rightAvailability;
            }

            return [
                (string) ($left['type'] ?? ''),
                (string) ($left['record_id'] ?? ''),
                (string) ($left['label'] ?? ''),
            ] <=> [
                (string) ($right['type'] ?? ''),
                (string) ($right['record_id'] ?? ''),
                (string) ($right['label'] ?? ''),
            ];
        });

        return array_values($references);
    }

    private function tenantReference(ManagedEnvironment $tenant): array
    {
        return [
            'type' => 'tenant',
            'record_id' => (string) $tenant->getKey(),
            'label' => $tenant->name,
            'action_label' => 'Open environment',
            'url' => ManagedEnvironmentLinks::viewUrl($tenant),
            'availability' => 'available',
            'freshness_note' => null,
            'access_reason' => null,
        ];
    }

    private function operationReference(OperationRun $run, ?ManagedEnvironment $tenant): array
    {
        return $this->modelReference(
            type: 'operation_run',
            record: $run,
            label: OperationRunLinks::identifier($run),
            actionLabel: OperationRunLinks::openLabel(),
            url: OperationRunLinks::tenantlessView($run),
            freshnessAt: $run->completed_at ?? $run->updated_at,
        );
    }

    /**
     * @return list<array<string, mixed>>
     */
    private function operationRelatedReferences(OperationRun $run, ?ManagedEnvironment $tenant): array
    {
        if (! $tenant instanceof ManagedEnvironment) {
            return [];
        }

        return collect($this->relatedNavigationResolver->operationLinks($run, $tenant))
            ->reject(static fn (string $url, string $label): bool => $label === OperationRunLinks::collectionLabel())
            ->map(fn (string $url, string $label): array => [
                'type' => 'operation_run',
                'record_id' => (string) $run->getKey(),
                'label' => $label,
                'action_label' => $label,
                'url' => $url,
                'availability' => 'available',
                'freshness_note' => null,
                'access_reason' => null,
            ])
            ->values()
            ->all();
    }

    private function modelReference(
        string $type,
        Model $record,
        string $label,
        string $actionLabel,
        ?string $url,
        mixed $freshnessAt = null,
    ): array {
        return [
            'type' => $type,
            'record_id' => (string) $record->getKey(),
            'label' => $label,
            'action_label' => $actionLabel,
            'url' => $url,
            'availability' => $url === null && $type !== 'stored_report' ? 'inaccessible' : 'available',
            'freshness_note' => $this->freshnessNote($freshnessAt),
            'access_reason' => $url === null && $type !== 'stored_report' ? 'Canonical destination is not available from this context.' : null,
        ];
    }

    private function missingReference(string $type, string $label, string $actionLabel): array
    {
        return [
            'type' => $type,
            'record_id' => null,
            'label' => $label,
            'action_label' => $actionLabel,
            'url' => null,
            'availability' => 'missing',
            'freshness_note' => null,
            'access_reason' => 'No authorized record is available for this support context.',
        ];
    }

    private function freshnessNote(mixed $value, string $prefix = 'Observed'): ?string
    {
        if ($value instanceof CarbonInterface) {
            return $prefix.': '.$value->toIso8601String();
        }

        if (is_string($value) && trim($value) !== '') {
            return $prefix.': '.trim($value);
        }

        return null;
    }

    /**
     * @param  list<array<string, mixed>>  $sections
     */
    private function freshnessState(array $sections): string
    {
        $availableCount = count(array_filter($sections, static fn (array $section): bool => $section['availability'] === 'available'));
        $missingCount = count(array_filter($sections, static fn (array $section): bool => $section['availability'] === 'missing'));
        $staleCount = count(array_filter($sections, static fn (array $section): bool => $section['availability'] === 'stale'));
        $redactedCount = count(array_filter($sections, static fn (array $section): bool => $section['availability'] === 'redacted'));

        if ($availableCount === 0 && $redactedCount === 0) {
            return 'missing_context';
        }

        if ($missingCount > 0 || $staleCount > 0) {
            return 'mixed';
        }

        return 'fresh';
    }

    /**
     * @param  list<array<string, mixed>>  $sections
     */
    private function completenessNote(array $sections): ?string
    {
        $missing = collect($sections)
            ->filter(static fn (array $section): bool => $section['availability'] === 'missing')
            ->pluck('label')
            ->values()
            ->all();

        if ($missing === []) {
            return null;
        }

        return 'Missing context: '.implode(', ', $missing).'.';
    }
}
