<?php

declare(strict_types=1);

namespace App\Support\Baselines;

use App\Models\BaselineProfile;
use App\Models\BaselineSnapshot;
use App\Models\BaselineTenantAssignment;
use App\Models\Finding;
use App\Models\InventoryItem;
use App\Models\OperationRun;
use App\Models\ManagedEnvironment;
use App\Services\Baselines\BaselineSnapshotTruthResolver;
use App\Support\OperationCatalog;
use App\Support\OperationRunStatus;
use App\Support\OperationRunType;
use App\Support\ReasonTranslation\ReasonPresenter;
use App\Support\Ui\OperatorExplanation\CountDescriptor;
use App\Support\Ui\OperatorExplanation\OperatorExplanationPattern;
use Illuminate\Support\Facades\Cache;

final class BaselineCompareStats
{
    /**
     * @param  array<string, int>  $severityCounts
     * @param  list<string>  $uncoveredTypes
     * @param  array<string, int>  $evidenceGapsTopReasons
     * @param  array{
     *     summary: array{
     *         count: int,
     *         by_reason: array<string, int>,
     *         detail_state: string,
     *         recorded_subjects_total: int,
     *         missing_detail_count: int
     *     },
     *     buckets: list<array{
     *         reason_code: string,
     *         reason_label: string,
     *         count: int,
     *         recorded_count: int,
     *         missing_detail_count: int,
     *         detail_state: string,
     *         search_text: string,
     *         rows: list<array{
     *             reason_code: string,
     *             reason_label: string,
     *             policy_type: string,
     *             subject_key: string,
     *             search_text: string
     *         }>
     *     }>
     * }  $evidenceGapDetails
     * @param  array<string, mixed>  $baselineCompareDiagnostics
     */
    private function __construct(
        public readonly string $state,
        public readonly ?string $message,
        public readonly ?string $profileName,
        public readonly ?int $profileId,
        public readonly ?int $snapshotId,
        public readonly ?int $duplicateNamePoliciesCount,
        public readonly ?int $duplicateNameSubjectsCount,
        public readonly ?int $operationRunId,
        public readonly ?int $findingsCount,
        public readonly array $severityCounts,
        public readonly ?string $lastComparedHuman,
        public readonly ?string $lastComparedIso,
        public readonly ?string $failureReason,
        public readonly ?string $reasonCode = null,
        public readonly ?string $reasonMessage = null,
        public readonly ?string $coverageStatus = null,
        public readonly ?int $uncoveredTypesCount = null,
        public readonly array $uncoveredTypes = [],
        public readonly ?string $fidelity = null,
        public readonly ?int $evidenceGapsCount = null,
        public readonly array $evidenceGapsTopReasons = [],
        public readonly ?array $rbacRoleDefinitionSummary = null,
        public readonly array $evidenceGapDetails = [],
        public readonly array $baselineCompareDiagnostics = [],
        public readonly ?int $evidenceGapStructuralCount = null,
        public readonly ?int $evidenceGapOperationalCount = null,
        public readonly ?int $evidenceGapTransientCount = null,
        public readonly ?bool $evidenceGapLegacyMode = null,
        public readonly int $overdueOpenFindingsCount = 0,
        public readonly int $expiringGovernanceCount = 0,
        public readonly int $lapsedGovernanceCount = 0,
        public readonly int $activeNonNewFindingsCount = 0,
        public readonly int $highSeverityActiveFindingsCount = 0,
    ) {}

    public static function forTenant(?ManagedEnvironment $tenant): self
    {
        if (! $tenant instanceof ManagedEnvironment) {
            return self::empty('no_tenant', 'No environment selected.');
        }

        $findingAttentionCounts = self::findingAttentionCounts($tenant);

        $assignment = BaselineTenantAssignment::query()
            ->with('baselineProfile')
            ->where('managed_environment_id', $tenant->getKey())
            ->first();

        if (! $assignment instanceof BaselineTenantAssignment) {
            return self::empty(
                'no_assignment',
                'This environment has no baseline assignment. A workspace manager can assign a baseline profile to this environment.',
                findingAttentionCounts: $findingAttentionCounts,
            );
        }

        $profile = $assignment->baselineProfile;

        if (! $profile instanceof BaselineProfile) {
            return self::empty(
                'no_assignment',
                'The assigned baseline profile no longer exists.',
                findingAttentionCounts: $findingAttentionCounts,
            );
        }

        $profileName = (string) $profile->name;
        $profileId = (int) $profile->getKey();
        $truthResolution = app(BaselineSnapshotTruthResolver::class)->resolveCompareSnapshot($profile);
        $effectiveSnapshot = $truthResolution['effective_snapshot'] ?? null;
        $snapshotId = $effectiveSnapshot instanceof BaselineSnapshot ? (int) $effectiveSnapshot->getKey() : null;
        $snapshotReasonCode = is_string($truthResolution['reason_code'] ?? null) ? (string) $truthResolution['reason_code'] : null;
        $latestCaptureRun = self::latestBaselineCaptureRun($profile);
        $snapshotReasonMessage = self::missingSnapshotMessage($snapshotReasonCode, $latestCaptureRun);

        try {
            $profileScope = $profile->normalizedScope();
            $overrideScope = $assignment->override_scope_jsonb !== null
                ? BaselineScope::fromJsonb(
                    is_array($assignment->override_scope_jsonb) ? $assignment->override_scope_jsonb : null,
                    allowEmptyLegacyAsNoOverride: true,
                )
                : null;
            $effectiveScope = BaselineScope::effective($profileScope, $overrideScope);
        } catch (InvalidArgumentException) {
            return self::empty(
                'invalid_scope',
                'The assigned baseline scope is invalid or no longer supported. A workspace manager must review the baseline definition.',
                findingAttentionCounts: $findingAttentionCounts,
            );
        }

        $duplicateNameStats = self::duplicateNameStats($tenant, $effectiveScope);
        $duplicateNamePoliciesCount = $duplicateNameStats['policy_count'];
        $duplicateNameSubjectsCount = $duplicateNameStats['subject_count'];

        if ($snapshotId === null) {
            return new self(
                state: 'no_snapshot',
                message: $snapshotReasonMessage ?? 'The baseline profile has no complete snapshot yet. A workspace manager needs to capture a baseline first.',
                profileName: $profileName,
                profileId: $profileId,
                snapshotId: null,
                duplicateNamePoliciesCount: $duplicateNamePoliciesCount,
                duplicateNameSubjectsCount: $duplicateNameSubjectsCount,
                operationRunId: null,
                findingsCount: null,
                severityCounts: [],
                lastComparedHuman: null,
                lastComparedIso: null,
                failureReason: null,
                reasonCode: $snapshotReasonCode,
                reasonMessage: $snapshotReasonMessage,
                overdueOpenFindingsCount: $findingAttentionCounts['overdue_open_findings_count'],
                expiringGovernanceCount: $findingAttentionCounts['expiring_governance_count'],
                lapsedGovernanceCount: $findingAttentionCounts['lapsed_governance_count'],
                activeNonNewFindingsCount: $findingAttentionCounts['active_non_new_findings_count'],
                highSeverityActiveFindingsCount: $findingAttentionCounts['high_severity_active_findings_count'],
            );
        }

        $latestRun = OperationRun::query()
            ->where('managed_environment_id', $tenant->getKey())
            ->whereIn('type', OperationCatalog::rawValuesForCanonical(OperationRunType::BaselineCompare->value))
            ->latest('id')
            ->first();

        [$coverageStatus, $uncoveredTypes, $fidelity] = self::coverageInfoForRun($latestRun);
        [$evidenceGapsCount, $evidenceGapsTopReasons] = self::evidenceGapSummaryForRun($latestRun);
        [$reasonCode, $reasonMessage] = self::reasonInfoForRun($latestRun);
        $rbacRoleDefinitionSummary = self::rbacRoleDefinitionSummaryForRun($latestRun);
        $evidenceGapDetails = self::evidenceGapDetailsForRun($latestRun);
        $baselineCompareDiagnostics = self::baselineCompareDiagnosticsForRun($latestRun);
        $evidenceGapSummary = is_array($evidenceGapDetails['summary'] ?? null) ? $evidenceGapDetails['summary'] : [];
        $evidenceGapStructuralCount = is_numeric($evidenceGapSummary['structural_count'] ?? null)
            ? (int) $evidenceGapSummary['structural_count']
            : null;
        $evidenceGapOperationalCount = is_numeric($evidenceGapSummary['operational_count'] ?? null)
            ? (int) $evidenceGapSummary['operational_count']
            : null;
        $evidenceGapTransientCount = is_numeric($evidenceGapSummary['transient_count'] ?? null)
            ? (int) $evidenceGapSummary['transient_count']
            : null;
        $evidenceGapLegacyMode = is_bool($evidenceGapSummary['legacy_mode'] ?? null)
            ? (bool) $evidenceGapSummary['legacy_mode']
            : null;

        // Active run (queued/running)
        if ($latestRun instanceof OperationRun && in_array($latestRun->status, ['queued', 'running'], true)) {
            return new self(
                state: 'comparing',
                message: 'A baseline comparison is currently in progress.',
                profileName: $profileName,
                profileId: $profileId,
                snapshotId: $snapshotId,
                duplicateNamePoliciesCount: $duplicateNamePoliciesCount,
                duplicateNameSubjectsCount: $duplicateNameSubjectsCount,
                operationRunId: (int) $latestRun->getKey(),
                findingsCount: null,
                severityCounts: [],
                lastComparedHuman: null,
                lastComparedIso: null,
                failureReason: null,
                reasonCode: $reasonCode,
                reasonMessage: $reasonMessage,
                coverageStatus: $coverageStatus,
                uncoveredTypesCount: $uncoveredTypes !== [] ? count($uncoveredTypes) : 0,
                uncoveredTypes: $uncoveredTypes,
                fidelity: $fidelity,
                evidenceGapsCount: $evidenceGapsCount,
                evidenceGapsTopReasons: $evidenceGapsTopReasons,
                rbacRoleDefinitionSummary: $rbacRoleDefinitionSummary,
                evidenceGapDetails: $evidenceGapDetails,
                baselineCompareDiagnostics: $baselineCompareDiagnostics,
                evidenceGapStructuralCount: $evidenceGapStructuralCount,
                evidenceGapOperationalCount: $evidenceGapOperationalCount,
                evidenceGapTransientCount: $evidenceGapTransientCount,
                evidenceGapLegacyMode: $evidenceGapLegacyMode,
                overdueOpenFindingsCount: $findingAttentionCounts['overdue_open_findings_count'],
                expiringGovernanceCount: $findingAttentionCounts['expiring_governance_count'],
                lapsedGovernanceCount: $findingAttentionCounts['lapsed_governance_count'],
                activeNonNewFindingsCount: $findingAttentionCounts['active_non_new_findings_count'],
                highSeverityActiveFindingsCount: $findingAttentionCounts['high_severity_active_findings_count'],
            );
        }

        // Failed run — explicit error state
        if ($latestRun instanceof OperationRun && $latestRun->outcome === 'failed') {
            $failureSummary = is_array($latestRun->failure_summary) ? $latestRun->failure_summary : [];
            $failureReason = $failureSummary['message']
                ?? $failureSummary['reason']
                ?? 'The comparison job failed. Check the run details for more information.';

            return new self(
                state: 'failed',
                message: (string) $failureReason,
                profileName: $profileName,
                profileId: $profileId,
                snapshotId: $snapshotId,
                duplicateNamePoliciesCount: $duplicateNamePoliciesCount,
                duplicateNameSubjectsCount: $duplicateNameSubjectsCount,
                operationRunId: (int) $latestRun->getKey(),
                findingsCount: null,
                severityCounts: [],
                lastComparedHuman: $latestRun->finished_at?->diffForHumans(),
                lastComparedIso: $latestRun->finished_at?->toIso8601String(),
                failureReason: (string) $failureReason,
                reasonCode: $reasonCode,
                reasonMessage: $reasonMessage,
                coverageStatus: $coverageStatus,
                uncoveredTypesCount: $uncoveredTypes !== [] ? count($uncoveredTypes) : 0,
                uncoveredTypes: $uncoveredTypes,
                fidelity: $fidelity,
                evidenceGapsCount: $evidenceGapsCount,
                evidenceGapsTopReasons: $evidenceGapsTopReasons,
                rbacRoleDefinitionSummary: $rbacRoleDefinitionSummary,
                evidenceGapDetails: $evidenceGapDetails,
                baselineCompareDiagnostics: $baselineCompareDiagnostics,
                evidenceGapStructuralCount: $evidenceGapStructuralCount,
                evidenceGapOperationalCount: $evidenceGapOperationalCount,
                evidenceGapTransientCount: $evidenceGapTransientCount,
                evidenceGapLegacyMode: $evidenceGapLegacyMode,
                overdueOpenFindingsCount: $findingAttentionCounts['overdue_open_findings_count'],
                expiringGovernanceCount: $findingAttentionCounts['expiring_governance_count'],
                lapsedGovernanceCount: $findingAttentionCounts['lapsed_governance_count'],
                activeNonNewFindingsCount: $findingAttentionCounts['active_non_new_findings_count'],
                highSeverityActiveFindingsCount: $findingAttentionCounts['high_severity_active_findings_count'],
            );
        }

        $lastComparedHuman = null;
        $lastComparedIso = null;

        if ($latestRun instanceof OperationRun && $latestRun->finished_at !== null) {
            $lastComparedHuman = $latestRun->finished_at->diffForHumans();
            $lastComparedIso = $latestRun->finished_at->toIso8601String();
        }

        $scopeKey = 'baseline_profile:'.$profile->getKey();

        // Single grouped query instead of 4 separate COUNT queries
        $severityRows = Finding::query()
            ->where('managed_environment_id', $tenant->getKey())
            ->where('finding_type', Finding::FINDING_TYPE_DRIFT)
            ->where('source', 'baseline.compare')
            ->where('scope_key', $scopeKey)
            ->whereIn('status', Finding::openStatusesForQuery())
            ->selectRaw('severity, count(*) as cnt')
            ->groupBy('severity')
            ->pluck('cnt', 'severity');

        $totalFindings = (int) $severityRows->sum();
        $severityCounts = [
            'high' => (int) ($severityRows[Finding::SEVERITY_HIGH] ?? 0),
            'medium' => (int) ($severityRows[Finding::SEVERITY_MEDIUM] ?? 0),
            'low' => (int) ($severityRows[Finding::SEVERITY_LOW] ?? 0),
        ];

        if ($totalFindings > 0) {
            return new self(
                state: 'ready',
                message: null,
                profileName: $profileName,
                profileId: $profileId,
                snapshotId: $snapshotId,
                duplicateNamePoliciesCount: $duplicateNamePoliciesCount,
                duplicateNameSubjectsCount: $duplicateNameSubjectsCount,
                operationRunId: $latestRun instanceof OperationRun ? (int) $latestRun->getKey() : null,
                findingsCount: $totalFindings,
                severityCounts: $severityCounts,
                lastComparedHuman: $lastComparedHuman,
                lastComparedIso: $lastComparedIso,
                failureReason: null,
                reasonCode: $reasonCode,
                reasonMessage: $reasonMessage,
                coverageStatus: $coverageStatus,
                uncoveredTypesCount: $uncoveredTypes !== [] ? count($uncoveredTypes) : 0,
                uncoveredTypes: $uncoveredTypes,
                fidelity: $fidelity,
                evidenceGapsCount: $evidenceGapsCount,
                evidenceGapsTopReasons: $evidenceGapsTopReasons,
                rbacRoleDefinitionSummary: $rbacRoleDefinitionSummary,
                evidenceGapDetails: $evidenceGapDetails,
                baselineCompareDiagnostics: $baselineCompareDiagnostics,
                evidenceGapStructuralCount: $evidenceGapStructuralCount,
                evidenceGapOperationalCount: $evidenceGapOperationalCount,
                evidenceGapTransientCount: $evidenceGapTransientCount,
                evidenceGapLegacyMode: $evidenceGapLegacyMode,
                overdueOpenFindingsCount: $findingAttentionCounts['overdue_open_findings_count'],
                expiringGovernanceCount: $findingAttentionCounts['expiring_governance_count'],
                lapsedGovernanceCount: $findingAttentionCounts['lapsed_governance_count'],
                activeNonNewFindingsCount: $findingAttentionCounts['active_non_new_findings_count'],
                highSeverityActiveFindingsCount: $findingAttentionCounts['high_severity_active_findings_count'],
            );
        }

        if ($latestRun instanceof OperationRun && $latestRun->status === 'completed' && in_array($latestRun->outcome, ['succeeded', 'partially_succeeded'], true)) {
            return new self(
                state: 'ready',
                message: $latestRun->outcome === 'succeeded'
                    ? 'No open drift findings for this baseline comparison. The tenant matches the baseline.'
                    : 'Comparison completed with warnings. Findings may be incomplete due to missing coverage.',
                profileName: $profileName,
                profileId: $profileId,
                snapshotId: $snapshotId,
                duplicateNamePoliciesCount: $duplicateNamePoliciesCount,
                duplicateNameSubjectsCount: $duplicateNameSubjectsCount,
                operationRunId: (int) $latestRun->getKey(),
                findingsCount: 0,
                severityCounts: $severityCounts,
                lastComparedHuman: $lastComparedHuman,
                lastComparedIso: $lastComparedIso,
                failureReason: null,
                reasonCode: $reasonCode,
                reasonMessage: $reasonMessage,
                coverageStatus: $coverageStatus,
                uncoveredTypesCount: $uncoveredTypes !== [] ? count($uncoveredTypes) : 0,
                uncoveredTypes: $uncoveredTypes,
                fidelity: $fidelity,
                evidenceGapsCount: $evidenceGapsCount,
                evidenceGapsTopReasons: $evidenceGapsTopReasons,
                rbacRoleDefinitionSummary: $rbacRoleDefinitionSummary,
                evidenceGapDetails: $evidenceGapDetails,
                baselineCompareDiagnostics: $baselineCompareDiagnostics,
                evidenceGapStructuralCount: $evidenceGapStructuralCount,
                evidenceGapOperationalCount: $evidenceGapOperationalCount,
                evidenceGapTransientCount: $evidenceGapTransientCount,
                evidenceGapLegacyMode: $evidenceGapLegacyMode,
                overdueOpenFindingsCount: $findingAttentionCounts['overdue_open_findings_count'],
                expiringGovernanceCount: $findingAttentionCounts['expiring_governance_count'],
                lapsedGovernanceCount: $findingAttentionCounts['lapsed_governance_count'],
                activeNonNewFindingsCount: $findingAttentionCounts['active_non_new_findings_count'],
                highSeverityActiveFindingsCount: $findingAttentionCounts['high_severity_active_findings_count'],
            );
        }

        return new self(
            state: 'idle',
            message: 'Baseline profile is assigned and has a snapshot. Run "Compare Now" to check for drift.',
            profileName: $profileName,
            profileId: $profileId,
            snapshotId: $snapshotId,
            duplicateNamePoliciesCount: $duplicateNamePoliciesCount,
            duplicateNameSubjectsCount: $duplicateNameSubjectsCount,
            operationRunId: null,
            findingsCount: null,
            severityCounts: $severityCounts,
            lastComparedHuman: $lastComparedHuman,
            lastComparedIso: $lastComparedIso,
            failureReason: null,
            reasonCode: $reasonCode,
            reasonMessage: $reasonMessage,
            coverageStatus: $coverageStatus,
            uncoveredTypesCount: $uncoveredTypes !== [] ? count($uncoveredTypes) : 0,
            uncoveredTypes: $uncoveredTypes,
            fidelity: $fidelity,
            evidenceGapsCount: $evidenceGapsCount,
            evidenceGapsTopReasons: $evidenceGapsTopReasons,
            rbacRoleDefinitionSummary: $rbacRoleDefinitionSummary,
            evidenceGapDetails: $evidenceGapDetails,
            baselineCompareDiagnostics: $baselineCompareDiagnostics,
            evidenceGapStructuralCount: $evidenceGapStructuralCount,
            evidenceGapOperationalCount: $evidenceGapOperationalCount,
            evidenceGapTransientCount: $evidenceGapTransientCount,
            evidenceGapLegacyMode: $evidenceGapLegacyMode,
            overdueOpenFindingsCount: $findingAttentionCounts['overdue_open_findings_count'],
            expiringGovernanceCount: $findingAttentionCounts['expiring_governance_count'],
            lapsedGovernanceCount: $findingAttentionCounts['lapsed_governance_count'],
            activeNonNewFindingsCount: $findingAttentionCounts['active_non_new_findings_count'],
            highSeverityActiveFindingsCount: $findingAttentionCounts['high_severity_active_findings_count'],
        );
    }

    /**
     * Create a DTO for widget consumption (only open/new findings).
     */
    public static function forWidget(?ManagedEnvironment $tenant): self
    {
        if (! $tenant instanceof ManagedEnvironment) {
            return self::empty('no_tenant', null);
        }

        $assignment = BaselineTenantAssignment::query()
            ->where('managed_environment_id', $tenant->getKey())
            ->with('baselineProfile')
            ->first();

        if (! $assignment instanceof BaselineTenantAssignment || $assignment->baselineProfile === null) {
            return self::empty('no_assignment', null);
        }

        $profile = $assignment->baselineProfile;
        $truthResolution = app(BaselineSnapshotTruthResolver::class)->resolveCompareSnapshot($profile);
        $effectiveSnapshot = $truthResolution['effective_snapshot'] ?? null;
        $snapshotId = $effectiveSnapshot instanceof BaselineSnapshot ? (int) $effectiveSnapshot->getKey() : null;
        $snapshotReasonCode = is_string($truthResolution['reason_code'] ?? null) ? (string) $truthResolution['reason_code'] : null;
        $snapshotReasonMessage = self::missingSnapshotMessage($snapshotReasonCode);
        $scopeKey = 'baseline_profile:'.$profile->getKey();

        $severityRows = Finding::query()
            ->where('managed_environment_id', $tenant->getKey())
            ->where('finding_type', Finding::FINDING_TYPE_DRIFT)
            ->where('source', 'baseline.compare')
            ->where('scope_key', $scopeKey)
            ->where('status', Finding::STATUS_NEW)
            ->selectRaw('severity, count(*) as cnt')
            ->groupBy('severity')
            ->pluck('cnt', 'severity');

        $totalFindings = (int) $severityRows->sum();

        $latestRun = OperationRun::query()
            ->where('managed_environment_id', $tenant->getKey())
            ->whereIn('type', OperationCatalog::rawValuesForCanonical(OperationRunType::BaselineCompare->value))
            ->where('context->baseline_profile_id', (string) $profile->getKey())
            ->whereNotNull('completed_at')
            ->latest('completed_at')
            ->first();

        return new self(
            state: $snapshotId === null ? 'no_snapshot' : ($totalFindings > 0 ? 'ready' : 'idle'),
            message: $snapshotId === null ? $snapshotReasonMessage : null,
            profileName: (string) $profile->name,
            profileId: (int) $profile->getKey(),
            snapshotId: $snapshotId,
            duplicateNamePoliciesCount: null,
            duplicateNameSubjectsCount: null,
            operationRunId: $latestRun instanceof OperationRun ? (int) $latestRun->getKey() : null,
            findingsCount: $totalFindings,
            severityCounts: [
                'high' => (int) ($severityRows[Finding::SEVERITY_HIGH] ?? 0),
                'medium' => (int) ($severityRows[Finding::SEVERITY_MEDIUM] ?? 0),
                'low' => (int) ($severityRows[Finding::SEVERITY_LOW] ?? 0),
            ],
            lastComparedHuman: $latestRun?->finished_at?->diffForHumans(),
            lastComparedIso: $latestRun?->finished_at?->toIso8601String(),
            failureReason: null,
            reasonCode: $snapshotReasonCode,
            reasonMessage: $snapshotReasonMessage,
        );
    }

    /**
     * @return array{policy_count: int, subject_count: int}
     */
    private static function duplicateNameStats(ManagedEnvironment $tenant, BaselineScope $effectiveScope): array
    {
        $policyTypes = $effectiveScope->allTypes();

        if ($policyTypes === []) {
            return [
                'policy_count' => 0,
                'subject_count' => 0,
            ];
        }

        $latestInventorySyncRunId = self::latestInventorySyncRunId($tenant);

        $compute = static function () use ($tenant, $policyTypes, $latestInventorySyncRunId): array {
            /**
             * @var array<string, int> $countsByKey
             */
            $countsByKey = [];

            $query = InventoryItem::query()
                ->where('managed_environment_id', (int) $tenant->getKey())
                ->whereIn('policy_type', $policyTypes)
                ->whereNotNull('display_name')
                ->select(['id', 'policy_type', 'display_name']);

            if (is_int($latestInventorySyncRunId) && $latestInventorySyncRunId > 0) {
                $query->where('last_seen_operation_run_id', $latestInventorySyncRunId);
            }

            $query
                ->orderBy('id')
                ->chunkById(1_000, function ($inventoryItems) use (&$countsByKey): void {
                    foreach ($inventoryItems as $inventoryItem) {
                        $displayName = is_string($inventoryItem->display_name) ? $inventoryItem->display_name : null;
                        $subjectKey = BaselineSubjectKey::fromDisplayName($displayName);

                        if ($subjectKey === null) {
                            continue;
                        }

                        $logicalKey = (string) $inventoryItem->policy_type.'|'.$subjectKey;
                        $countsByKey[$logicalKey] = ($countsByKey[$logicalKey] ?? 0) + 1;
                    }
                });

            $duplicatePolicies = 0;
            $duplicateSubjects = 0;

            foreach ($countsByKey as $count) {
                if ($count > 1) {
                    $duplicateSubjects++;
                    $duplicatePolicies += $count;
                }
            }

            return [
                'policy_count' => $duplicatePolicies,
                'subject_count' => $duplicateSubjects,
            ];
        };

        if (app()->environment('testing')) {
            return $compute();
        }

        $cacheKey = sprintf(
            'baseline_compare:tenant:%d:duplicate_names:%s:%s',
            (int) $tenant->getKey(),
            hash('sha256', implode('|', $policyTypes)),
            $latestInventorySyncRunId ?? 'all',
        );

        /** @var array{policy_count: int, subject_count: int} $stats */
        $stats = Cache::remember($cacheKey, now()->addSeconds(60), $compute);

        return $stats;
    }

    private static function latestInventorySyncRunId(ManagedEnvironment $tenant): ?int
    {
        $run = OperationRun::query()
            ->where('managed_environment_id', (int) $tenant->getKey())
            ->where('type', OperationRunType::InventorySync->value)
            ->where('status', OperationRunStatus::Completed->value)
            ->orderByDesc('completed_at')
            ->orderByDesc('id')
            ->first(['id']);

        return $run instanceof OperationRun ? (int) $run->getKey() : null;
    }

    /**
     * @return array{0: ?string, 1: list<string>, 2: ?string}
     */
    private static function coverageInfoForRun(?OperationRun $run): array
    {
        if (! $run instanceof OperationRun) {
            return [null, [], null];
        }

        $context = is_array($run->context) ? $run->context : [];
        $baselineCompare = $context['baseline_compare'] ?? null;

        if (! is_array($baselineCompare)) {
            return [null, [], null];
        }

        $coverage = $baselineCompare['coverage'] ?? null;
        $coverage = is_array($coverage) ? $coverage : [];

        $proof = $coverage['proof'] ?? null;
        $proof = is_bool($proof) ? $proof : null;

        $uncoveredTypes = $coverage['uncovered_types'] ?? null;
        $uncoveredTypes = is_array($uncoveredTypes) ? array_values(array_filter($uncoveredTypes, 'is_string')) : [];
        $uncoveredTypes = array_values(array_unique(array_filter(array_map('trim', $uncoveredTypes), fn (string $type): bool => $type !== '')));
        sort($uncoveredTypes, SORT_STRING);

        $coverageStatus = null;

        if ($proof === false) {
            $coverageStatus = 'unproven';
        } elseif ($uncoveredTypes !== []) {
            $coverageStatus = 'warning';
        } elseif ($proof === true) {
            $coverageStatus = 'ok';
        }

        $fidelity = $baselineCompare['fidelity'] ?? null;
        $fidelity = is_string($fidelity) ? trim($fidelity) : null;
        $fidelity = $fidelity !== '' ? $fidelity : null;

        return [$coverageStatus, $uncoveredTypes, $fidelity];
    }

    /**
     * @return array{0: ?string, 1: ?string}
     */
    private static function reasonInfoForRun(?OperationRun $run): array
    {
        if (! $run instanceof OperationRun) {
            return [null, null];
        }

        $context = is_array($run->context) ? $run->context : [];
        $baselineCompare = $context['baseline_compare'] ?? null;

        if (! is_array($baselineCompare)) {
            return [null, null];
        }

        $reasonCode = $baselineCompare['reason_code'] ?? null;
        $reasonCode = is_string($reasonCode) ? trim($reasonCode) : null;
        $reasonCode = $reasonCode !== '' ? $reasonCode : null;

        $enum = $reasonCode !== null ? BaselineCompareReasonCode::tryFrom($reasonCode) : null;

        return [$reasonCode, $enum?->message()];
    }

    /**
     * @return array{0: ?int, 1: array<string, int>}
     */
    private static function evidenceGapSummaryForRun(?OperationRun $run): array
    {
        if (! $run instanceof OperationRun) {
            return [null, []];
        }

        $details = self::evidenceGapDetailsForRun($run);
        $summary = is_array($details['summary'] ?? null) ? $details['summary'] : [];
        $count = is_numeric($summary['count'] ?? null) ? (int) $summary['count'] : null;
        $byReason = is_array($summary['by_reason'] ?? null) ? $summary['by_reason'] : [];

        return [$count, array_slice($byReason, 0, 6, true)];
    }

    /**
     * @return array{
     *     summary: array{
     *         count: int,
     *         by_reason: array<string, int>,
     *         detail_state: string,
     *         recorded_subjects_total: int,
     *         missing_detail_count: int
     *     },
     *     buckets: list<array{
     *         reason_code: string,
     *         reason_label: string,
     *         count: int,
     *         recorded_count: int,
     *         missing_detail_count: int,
     *         detail_state: string,
     *         search_text: string,
     *         rows: list<array{
     *             reason_code: string,
     *             reason_label: string,
     *             policy_type: string,
     *             subject_key: string,
     *             search_text: string
     *         }>
     *     }>
     * }
     */
    private static function evidenceGapDetailsForRun(?OperationRun $run): array
    {
        if (! $run instanceof OperationRun) {
            return BaselineCompareEvidenceGapDetails::fromContext([]);
        }

        return BaselineCompareEvidenceGapDetails::fromOperationRun($run);
    }

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

        $context = is_array($run->context) ? $run->context : [];
        $baselineCompare = $context['baseline_compare'] ?? null;

        if (! is_array($baselineCompare)) {
            return [];
        }

        return BaselineCompareEvidenceGapDetails::diagnosticsPayload($baselineCompare);
    }

    /**
     * @return array{total_compared: int, unchanged: int, modified: int, missing: int, unexpected: int}|null
     */
    private static function rbacRoleDefinitionSummaryForRun(?OperationRun $run): ?array
    {
        if (! $run instanceof OperationRun) {
            return null;
        }

        $context = is_array($run->context) ? $run->context : [];
        $baselineCompare = $context['baseline_compare'] ?? null;
        $summary = is_array($baselineCompare) ? ($baselineCompare['rbac_role_definitions'] ?? null) : null;

        if (! is_array($summary)) {
            return null;
        }

        return [
            'total_compared' => (int) ($summary['total_compared'] ?? 0),
            'unchanged' => (int) ($summary['unchanged'] ?? 0),
            'modified' => (int) ($summary['modified'] ?? 0),
            'missing' => (int) ($summary['missing'] ?? 0),
            'unexpected' => (int) ($summary['unexpected'] ?? 0),
        ];
    }

    /**
     * @return array{
     *     overdue_open_findings_count: int,
     *     expiring_governance_count: int,
     *     lapsed_governance_count: int,
     *     active_non_new_findings_count: int,
     *     high_severity_active_findings_count: int
     * }
     */
    private static function findingAttentionCounts(ManagedEnvironment $tenant): array
    {
        $tenantId = (int) $tenant->getKey();

        $overdueOpenFindingsCount = Finding::query()
            ->where('managed_environment_id', $tenantId)
            ->whereIn('status', Finding::openStatusesForQuery())
            ->whereNotNull('due_at')
            ->where('due_at', '<', now())
            ->count();

        $expiringGovernanceCount = Finding::query()
            ->where('managed_environment_id', $tenantId)
            ->where('status', Finding::STATUS_RISK_ACCEPTED)
            ->whereHas('findingException', function ($query): void {
                $query->where('current_validity_state', \App\Models\FindingException::VALIDITY_EXPIRING);
            })
            ->count();

        $lapsedGovernanceCount = Finding::query()
            ->where('managed_environment_id', $tenantId)
            ->where('status', Finding::STATUS_RISK_ACCEPTED)
            ->where(function ($query): void {
                $query
                    ->whereDoesntHave('findingException')
                    ->orWhereHas('findingException', function ($exceptionQuery): void {
                        $exceptionQuery->whereIn('current_validity_state', [
                            \App\Models\FindingException::VALIDITY_EXPIRED,
                            \App\Models\FindingException::VALIDITY_REVOKED,
                            \App\Models\FindingException::VALIDITY_REJECTED,
                            \App\Models\FindingException::VALIDITY_MISSING_SUPPORT,
                        ]);
                    });
            })
            ->count();

        $activeNonNewFindingsCount = Finding::query()
            ->where('managed_environment_id', $tenantId)
            ->whereIn('status', [
                Finding::STATUS_TRIAGED,
                Finding::STATUS_IN_PROGRESS,
                Finding::STATUS_REOPENED,
            ])
            ->count();

        $highSeverityActiveFindingsCount = Finding::query()
            ->where('managed_environment_id', $tenantId)
            ->whereIn('status', Finding::openStatusesForQuery())
            ->whereIn('severity', [
                Finding::SEVERITY_HIGH,
                Finding::SEVERITY_CRITICAL,
            ])
            ->count();

        return [
            'overdue_open_findings_count' => $overdueOpenFindingsCount,
            'expiring_governance_count' => $expiringGovernanceCount,
            'lapsed_governance_count' => $lapsedGovernanceCount,
            'active_non_new_findings_count' => $activeNonNewFindingsCount,
            'high_severity_active_findings_count' => $highSeverityActiveFindingsCount,
        ];
    }

    public function operatorExplanation(): OperatorExplanationPattern
    {
        /** @var BaselineCompareExplanationRegistry $registry */
        $registry = app(BaselineCompareExplanationRegistry::class);

        return $registry->forStats($this);
    }

    public function summaryAssessment(): BaselineCompareSummaryAssessment
    {
        /** @var BaselineCompareSummaryAssessor $assessor */
        $assessor = app(BaselineCompareSummaryAssessor::class);

        return $assessor->assess($this);
    }

    public function toTenantGovernanceAggregate(ManagedEnvironment $tenant): TenantGovernanceAggregate
    {
        $summaryAssessment = $this->summaryAssessment();

        return new TenantGovernanceAggregate(
            tenantId: (int) $tenant->getKey(),
            workspaceId: (int) $tenant->workspace_id,
            profileName: $this->profileName,
            compareState: $this->state,
            stateFamily: $summaryAssessment->stateFamily,
            tone: $summaryAssessment->tone,
            headline: $summaryAssessment->headline,
            supportingMessage: $summaryAssessment->supportingMessage,
            reasonCode: $summaryAssessment->reasonCode,
            lastComparedLabel: $summaryAssessment->lastComparedLabel,
            visibleDriftFindingsCount: $summaryAssessment->findingsVisibleCount,
            overdueOpenFindingsCount: $this->overdueOpenFindingsCount,
            expiringGovernanceCount: $this->expiringGovernanceCount,
            lapsedGovernanceCount: $this->lapsedGovernanceCount,
            activeNonNewFindingsCount: $this->activeNonNewFindingsCount,
            highSeverityActiveFindingsCount: $this->highSeverityActiveFindingsCount,
            nextActionLabel: $summaryAssessment->nextActionLabel(),
            nextActionTarget: $summaryAssessment->nextActionTarget(),
            positiveClaimAllowed: $summaryAssessment->positiveClaimAllowed,
            stats: $this,
            summaryAssessment: $summaryAssessment,
        );
    }

    /**
     * @return array<int, array{
     *     label: string,
     *     value: int,
     *     role: string,
     *     qualifier: ?string,
     *     visibilityTier: string
     * }>
     */
    public function explanationCountDescriptors(): array
    {
        return array_map(
            static fn (CountDescriptor $descriptor): array => $descriptor->toArray(),
            $this->operatorExplanation()->countDescriptors,
        );
    }

    private static function empty(
        string $state,
        ?string $message,
        ?string $profileName = null,
        ?int $profileId = null,
        ?int $duplicateNamePoliciesCount = null,
        ?int $duplicateNameSubjectsCount = null,
        array $findingAttentionCounts = [],
    ): self {
        return new self(
            state: $state,
            message: $message,
            profileName: $profileName,
            profileId: $profileId,
            snapshotId: null,
            duplicateNamePoliciesCount: $duplicateNamePoliciesCount,
            duplicateNameSubjectsCount: $duplicateNameSubjectsCount,
            operationRunId: null,
            findingsCount: null,
            severityCounts: [],
            lastComparedHuman: null,
            lastComparedIso: null,
            failureReason: null,
            overdueOpenFindingsCount: (int) ($findingAttentionCounts['overdue_open_findings_count'] ?? 0),
            expiringGovernanceCount: (int) ($findingAttentionCounts['expiring_governance_count'] ?? 0),
            lapsedGovernanceCount: (int) ($findingAttentionCounts['lapsed_governance_count'] ?? 0),
            activeNonNewFindingsCount: (int) ($findingAttentionCounts['active_non_new_findings_count'] ?? 0),
            highSeverityActiveFindingsCount: (int) ($findingAttentionCounts['high_severity_active_findings_count'] ?? 0),
        );
    }

    private static function latestBaselineCaptureRun(BaselineProfile $profile): ?OperationRun
    {
        return OperationRun::query()
            ->where('workspace_id', (int) $profile->workspace_id)
            ->where('type', OperationRunType::BaselineCapture->value)
            ->where('context->baseline_profile_id', (int) $profile->getKey())
            ->where('status', OperationRunStatus::Completed->value)
            ->orderByDesc('completed_at')
            ->orderByDesc('id')
            ->first();
    }

    private static function missingSnapshotMessage(?string $reasonCode, ?OperationRun $latestCaptureRun = null): ?string
    {
        $latestCaptureEnvelope = $latestCaptureRun instanceof OperationRun
            ? app(ReasonPresenter::class)->forOperationRun($latestCaptureRun, 'artifact_truth')
            : null;

        if ($latestCaptureEnvelope !== null
            && in_array($latestCaptureEnvelope->internalCode, [
                BaselineReasonCodes::CAPTURE_INVENTORY_BLOCKED,
                BaselineReasonCodes::CAPTURE_INVENTORY_FAILED,
                BaselineReasonCodes::CAPTURE_UNUSABLE_COVERAGE,
                BaselineReasonCodes::CAPTURE_ZERO_SUBJECTS,
            ], true)
            && trim($latestCaptureEnvelope->shortExplanation) !== '') {
            return $latestCaptureEnvelope->shortExplanation;
        }

        return match ($reasonCode) {
            BaselineReasonCodes::COMPARE_SNAPSHOT_BUILDING => 'The latest baseline capture is still building. Compare becomes available after a complete snapshot is finalized.',
            BaselineReasonCodes::COMPARE_SNAPSHOT_INCOMPLETE => 'The latest baseline capture is incomplete and there is no current complete snapshot to compare against.',
            BaselineReasonCodes::COMPARE_NO_CONSUMABLE_SNAPSHOT,
            BaselineReasonCodes::COMPARE_NO_ACTIVE_SNAPSHOT => 'The baseline profile has no complete snapshot yet. A workspace manager needs to capture a baseline first.',
            default => null,
        };
    }
}
