<?php

declare(strict_types=1);

namespace App\Support\Badges;

use InvalidArgumentException;

final class OperatorOutcomeTaxonomy
{
    /**
     * @var array<string, array<string, array{
     *     axis: string,
     *     label: string,
     *     color: string,
     *     classification: string,
     *     next_action_policy: string,
     *     legacy_aliases: list<string>,
     *     diagnostic_label?: string|null,
     *     notes: string
     * }>>
     */
    private const ENTRIES = [
        'governance_artifact_existence' => [
            'not_created' => [
                'axis' => 'artifact_existence',
                'label' => 'Not created yet',
                'color' => 'info',
                'classification' => 'primary',
                'next_action_policy' => 'optional',
                'legacy_aliases' => ['No artifact'],
                'notes' => 'The intended artifact has not been produced yet.',
            ],
            'historical_only' => [
                'axis' => 'artifact_existence',
                'label' => 'Historical artifact',
                'color' => 'gray',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Historical only'],
                'notes' => 'The artifact remains readable for history but is no longer the current working artifact.',
            ],
            'created' => [
                'axis' => 'artifact_existence',
                'label' => 'Artifact available',
                'color' => 'success',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Created'],
                'notes' => 'The intended artifact exists and can be inspected.',
            ],
            'created_but_not_usable' => [
                'axis' => 'artifact_existence',
                'label' => 'Artifact not usable',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Created but not usable'],
                'notes' => 'The artifact record exists, but the operator cannot safely rely on it for the primary task.',
            ],
        ],
        'governance_artifact_content' => [
            'trusted' => [
                'axis' => 'data_coverage',
                'label' => 'Trustworthy artifact',
                'color' => 'success',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Trusted'],
                'notes' => 'The artifact content is fit for the primary operator workflow.',
            ],
            'partial' => [
                'axis' => 'data_coverage',
                'label' => 'Partially complete',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Partially complete'],
                'notes' => 'The artifact exists but key content is incomplete.',
            ],
            'missing_input' => [
                'axis' => 'data_coverage',
                'label' => 'Missing input',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Missing'],
                'notes' => 'The artifact is blocked by missing upstream inputs.',
            ],
            'metadata_only' => [
                'axis' => 'evidence_depth',
                'label' => 'Metadata only',
                'color' => 'info',
                'classification' => 'diagnostic',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Metadata-only'],
                'notes' => 'Only metadata is available. This is diagnostic context and should not replace the primary truth state.',
            ],
            'reference_only' => [
                'axis' => 'evidence_depth',
                'label' => 'Reference only',
                'color' => 'info',
                'classification' => 'diagnostic',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Reference-only'],
                'notes' => 'Only reference placeholders are available. This is diagnostic context and should not replace the primary truth state.',
            ],
            'empty' => [
                'axis' => 'data_coverage',
                'label' => 'Empty snapshot',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Empty'],
                'notes' => 'The artifact exists but captured no usable content.',
            ],
            'unsupported' => [
                'axis' => 'product_support_maturity',
                'label' => 'Support limited',
                'color' => 'gray',
                'classification' => 'diagnostic',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Unsupported'],
                'notes' => 'The product is representing the source with limited fidelity. This remains diagnostic unless a stronger truth dimension applies.',
            ],
        ],
        'governance_artifact_freshness' => [
            'current' => [
                'axis' => 'data_freshness',
                'label' => 'Current',
                'color' => 'success',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Fresh'],
                'notes' => 'The available artifact is current enough for the primary task.',
            ],
            'stale' => [
                'axis' => 'data_freshness',
                'label' => 'Refresh recommended',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'optional',
                'legacy_aliases' => ['Refresh recommended'],
                'notes' => 'The artifact exists but should be refreshed before relying on it.',
            ],
            'unknown' => [
                'axis' => 'data_freshness',
                'label' => 'Freshness unknown',
                'color' => 'gray',
                'classification' => 'diagnostic',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Unknown'],
                'notes' => 'The system cannot determine freshness from the available payload.',
            ],
        ],
        'governance_artifact_publication_readiness' => [
            'not_applicable' => [
                'axis' => 'publication_readiness',
                'label' => 'Not applicable',
                'color' => 'gray',
                'classification' => 'diagnostic',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['N/A'],
                'notes' => 'Publication readiness does not apply to this artifact family.',
            ],
            'internal_only' => [
                'axis' => 'publication_readiness',
                'label' => 'Internal only',
                'color' => 'info',
                'classification' => 'primary',
                'next_action_policy' => 'optional',
                'legacy_aliases' => ['Draft'],
                'notes' => 'The artifact is useful internally but not ready for stakeholder delivery.',
            ],
            'publishable' => [
                'axis' => 'publication_readiness',
                'label' => 'Publishable',
                'color' => 'success',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Ready'],
                'notes' => 'The artifact is ready for stakeholder publication or export.',
            ],
            'blocked' => [
                'axis' => 'publication_readiness',
                'label' => 'Publication blocked',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Not publishable'],
                'notes' => 'The artifact exists but is blocked from publication or export.',
            ],
        ],
        'governance_artifact_actionability' => [
            'none' => [
                'axis' => 'operator_actionability',
                'label' => 'No action needed',
                'color' => 'gray',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['No follow-up'],
                'notes' => 'The current non-green state is informational only and does not require action.',
            ],
            'optional' => [
                'axis' => 'operator_actionability',
                'label' => 'Review recommended',
                'color' => 'info',
                'classification' => 'primary',
                'next_action_policy' => 'optional',
                'legacy_aliases' => ['Optional follow-up'],
                'notes' => 'The artifact can be used, but the operator should review the follow-up guidance.',
            ],
            'required' => [
                'axis' => 'operator_actionability',
                'label' => 'Action required',
                'color' => 'danger',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Required follow-up'],
                'notes' => 'The artifact cannot be trusted for the primary task until an operator addresses the issue.',
            ],
        ],
        'operator_explanation_evaluation_result' => [
            'full_result' => [
                'axis' => 'execution_outcome',
                'label' => 'Complete result',
                'color' => 'success',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Full result'],
                'notes' => 'The result can be read as complete for the intended operator decision.',
            ],
            'incomplete_result' => [
                'axis' => 'data_coverage',
                'label' => 'Incomplete result',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Partial result'],
                'notes' => 'A result exists, but missing or partial coverage limits what it means.',
            ],
            'suppressed_result' => [
                'axis' => 'data_coverage',
                'label' => 'Suppressed result',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Suppressed'],
                'notes' => 'Normal output was intentionally suppressed because the system could not safely present it as final.',
            ],
            'failed_result' => [
                'axis' => 'execution_outcome',
                'label' => 'Failed result',
                'color' => 'danger',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Execution failed'],
                'notes' => 'The workflow ended without producing a usable result and needs operator investigation.',
            ],
            'no_result' => [
                'axis' => 'execution_outcome',
                'label' => 'No issues detected',
                'color' => 'success',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['No result'],
                'notes' => 'The workflow produced no decision-relevant follow-up for the operator.',
            ],
            'unavailable' => [
                'axis' => 'execution_outcome',
                'label' => 'Result unavailable',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Unavailable'],
                'notes' => 'A usable result is not currently available for this surface.',
            ],
        ],
        'operator_explanation_trustworthiness' => [
            'trustworthy' => [
                'axis' => 'data_coverage',
                'label' => 'Trustworthy',
                'color' => 'success',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Decision grade'],
                'notes' => 'The operator can rely on this result for the intended task.',
            ],
            'limited_confidence' => [
                'axis' => 'data_coverage',
                'label' => 'Limited confidence',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'optional',
                'legacy_aliases' => ['Use with caution'],
                'notes' => 'The result is still useful, but the operator should account for documented limitations.',
            ],
            'diagnostic_only' => [
                'axis' => 'evidence_depth',
                'label' => 'Diagnostic only',
                'color' => 'info',
                'classification' => 'diagnostic',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Diagnostics only'],
                'notes' => 'The result is suitable for diagnostics only, not for a final decision.',
            ],
            'unusable' => [
                'axis' => 'operator_actionability',
                'label' => 'Not usable yet',
                'color' => 'danger',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Unusable'],
                'notes' => 'The operator should not rely on this result until the blocking issue is resolved.',
            ],
        ],
        'baseline_snapshot_lifecycle' => [
            'building' => [
                'axis' => 'execution_lifecycle',
                'label' => 'Building',
                'color' => 'info',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['In progress'],
                'notes' => 'The snapshot row exists, but completion proof has not finished yet.',
            ],
            'complete' => [
                'axis' => 'data_coverage',
                'label' => 'Complete',
                'color' => 'success',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Ready'],
                'notes' => 'The snapshot passed completion proof and is eligible for compare.',
            ],
            'incomplete' => [
                'axis' => 'data_coverage',
                'label' => 'Incomplete',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Partial'],
                'notes' => 'The snapshot exists but did not finish cleanly and is not usable for compare.',
            ],
            'superseded' => [
                'axis' => 'data_freshness',
                'label' => 'Superseded',
                'color' => 'gray',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Historical'],
                'notes' => 'A newer complete snapshot is the effective current baseline truth.',
            ],
        ],
        'operation_run_status' => [
            'queued' => [
                'axis' => 'execution_lifecycle',
                'label' => 'Queued for execution',
                'color' => 'info',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Queued'],
                'notes' => 'Execution is waiting for a worker to start the run.',
            ],
            'running' => [
                'axis' => 'execution_lifecycle',
                'label' => 'In progress',
                'color' => 'info',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Running'],
                'notes' => 'Execution is currently running.',
            ],
            'completed' => [
                'axis' => 'execution_lifecycle',
                'label' => 'Operation finished',
                'color' => 'gray',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Completed'],
                'notes' => 'Execution has reached a terminal state and the outcome badge carries the primary meaning.',
            ],
        ],
        'operation_run_outcome' => [
            'pending' => [
                'axis' => 'execution_outcome',
                'label' => 'Awaiting result',
                'color' => 'gray',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Pending'],
                'notes' => 'Execution has not produced a terminal outcome yet.',
            ],
            'succeeded' => [
                'axis' => 'execution_outcome',
                'label' => 'Completed successfully',
                'color' => 'success',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Succeeded'],
                'notes' => 'The operation finished without operator follow-up.',
            ],
            'partially_succeeded' => [
                'axis' => 'execution_outcome',
                'label' => 'Completed with follow-up',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'optional',
                'legacy_aliases' => ['Partially succeeded', 'Partial'],
                'notes' => 'The operation finished but needs operator review or cleanup.',
            ],
            'blocked' => [
                'axis' => 'execution_outcome',
                'label' => 'Blocked by prerequisite',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Blocked'],
                'notes' => 'Execution could not start or continue until a prerequisite is fixed.',
            ],
            'failed' => [
                'axis' => 'execution_outcome',
                'label' => 'Execution failed',
                'color' => 'danger',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Failed'],
                'notes' => 'Execution ended unsuccessfully and needs operator attention.',
            ],
            'cancelled' => [
                'axis' => 'execution_outcome',
                'label' => 'Cancelled',
                'color' => 'gray',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Cancelled'],
                'notes' => 'Execution was intentionally stopped.',
            ],
        ],
        'evidence_completeness' => [
            'complete' => [
                'axis' => 'data_coverage',
                'label' => 'Coverage ready',
                'color' => 'success',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Complete'],
                'notes' => 'Required evidence is present.',
            ],
            'partial' => [
                'axis' => 'data_coverage',
                'label' => 'Coverage incomplete',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Partial'],
                'notes' => 'Some required evidence dimensions are still missing.',
            ],
            'missing' => [
                'axis' => 'data_coverage',
                'label' => 'Not collected yet',
                'color' => 'info',
                'classification' => 'primary',
                'next_action_policy' => 'optional',
                'legacy_aliases' => ['Missing'],
                'notes' => 'No evidence has been captured for this slice yet. This is not a failure by itself.',
            ],
            'stale' => [
                'axis' => 'data_freshness',
                'label' => 'Refresh recommended',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'optional',
                'legacy_aliases' => ['Stale'],
                'notes' => 'Evidence exists but is old enough that the operator should refresh it before relying on it.',
            ],
        ],
        'environment_review_completeness' => [
            'complete' => [
                'axis' => 'data_coverage',
                'label' => 'Review inputs ready',
                'color' => 'success',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Complete'],
                'notes' => 'The review has the evidence inputs it needs.',
            ],
            'partial' => [
                'axis' => 'data_coverage',
                'label' => 'Review inputs incomplete',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Partial'],
                'notes' => 'Some review sections still need inputs.',
            ],
            'missing' => [
                'axis' => 'data_coverage',
                'label' => 'Review input pending',
                'color' => 'info',
                'classification' => 'primary',
                'next_action_policy' => 'optional',
                'legacy_aliases' => ['Missing'],
                'notes' => 'The review has not been anchored to usable evidence yet.',
            ],
            'stale' => [
                'axis' => 'data_freshness',
                'label' => 'Refresh review inputs',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'optional',
                'legacy_aliases' => ['Stale'],
                'notes' => 'The review input exists but should be refreshed before stakeholder use.',
            ],
        ],
        'baseline_snapshot_fidelity' => [
            'full' => [
                'axis' => 'evidence_depth',
                'label' => 'Detailed evidence',
                'color' => 'success',
                'classification' => 'diagnostic',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Full'],
                'notes' => 'Full structured evidence detail is available.',
            ],
            'partial' => [
                'axis' => 'evidence_depth',
                'label' => 'Mixed evidence detail',
                'color' => 'info',
                'classification' => 'diagnostic',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Partial'],
                'notes' => 'Some items have full detail while others are metadata-only.',
            ],
            'reference_only' => [
                'axis' => 'evidence_depth',
                'label' => 'Metadata only',
                'color' => 'info',
                'classification' => 'diagnostic',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Reference only'],
                'notes' => 'Only reference metadata is available for this capture.',
            ],
            'unsupported' => [
                'axis' => 'product_support_maturity',
                'label' => 'Support limited',
                'color' => 'gray',
                'classification' => 'diagnostic',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Unsupported'],
                'diagnostic_label' => 'Fallback renderer',
                'notes' => 'The renderer fell back to a lower-fidelity representation. This is diagnostic context, not a governance gap.',
            ],
        ],
        'baseline_snapshot_gap_status' => [
            'clear' => [
                'axis' => 'data_coverage',
                'label' => 'No follow-up needed',
                'color' => 'success',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['No gaps'],
                'notes' => 'The captured group does not contain unresolved coverage gaps.',
            ],
            'gaps_present' => [
                'axis' => 'data_coverage',
                'label' => 'Coverage gaps need review',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Gaps present'],
                'notes' => 'The captured group has unresolved gaps that should be reviewed.',
            ],
        ],
        'restore_run_status' => [
            'draft' => [
                'axis' => 'execution_lifecycle',
                'label' => 'Draft',
                'color' => 'gray',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Draft'],
                'notes' => 'The restore run has not been prepared yet.',
            ],
            'scoped' => [
                'axis' => 'execution_lifecycle',
                'label' => 'Scope selected',
                'color' => 'gray',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Scoped'],
                'notes' => 'Items were selected for restore.',
            ],
            'checked' => [
                'axis' => 'execution_lifecycle',
                'label' => 'Checks complete',
                'color' => 'gray',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Checked'],
                'notes' => 'Safety checks were completed for this operation.',
            ],
            'previewed' => [
                'axis' => 'execution_lifecycle',
                'label' => 'Preview ready',
                'color' => 'gray',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Previewed'],
                'notes' => 'A dry-run preview is available for review.',
            ],
            'pending' => [
                'axis' => 'execution_lifecycle',
                'label' => 'Pending execution',
                'color' => 'gray',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Pending'],
                'notes' => 'Execution has not been queued yet.',
            ],
            'queued' => [
                'axis' => 'execution_lifecycle',
                'label' => 'Queued for execution',
                'color' => 'info',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Queued'],
                'notes' => 'Execution is queued and waiting for a worker.',
            ],
            'running' => [
                'axis' => 'execution_lifecycle',
                'label' => 'Applying restore',
                'color' => 'info',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Running'],
                'notes' => 'Execution is currently applying restore work.',
            ],
            'completed' => [
                'axis' => 'execution_outcome',
                'label' => 'Applied successfully',
                'color' => 'success',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Completed'],
                'notes' => 'The restore operation finished successfully.',
            ],
            'partial' => [
                'axis' => 'execution_outcome',
                'label' => 'Applied with follow-up',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'optional',
                'legacy_aliases' => ['Partial'],
                'notes' => 'The restore operation finished but needs follow-up on a subset of items.',
            ],
            'failed' => [
                'axis' => 'execution_outcome',
                'label' => 'Restore failed',
                'color' => 'danger',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Failed'],
                'notes' => 'The restore run did not complete successfully.',
            ],
            'cancelled' => [
                'axis' => 'execution_outcome',
                'label' => 'Cancelled',
                'color' => 'gray',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Cancelled'],
                'notes' => 'Execution was intentionally cancelled.',
            ],
            'aborted' => [
                'axis' => 'execution_outcome',
                'label' => 'Stopped early',
                'color' => 'gray',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Aborted'],
                'notes' => 'Execution stopped before the normal terminal path completed.',
            ],
            'completed_with_errors' => [
                'axis' => 'execution_outcome',
                'label' => 'Applied with follow-up',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'optional',
                'legacy_aliases' => ['Completed with errors'],
                'notes' => 'Execution completed but still needs follow-up on failed items.',
            ],
        ],
        'restore_result_status' => [
            'applied' => [
                'axis' => 'item_result',
                'label' => 'Applied',
                'color' => 'success',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Applied'],
                'notes' => 'The item was applied successfully.',
            ],
            'dry_run' => [
                'axis' => 'item_result',
                'label' => 'Preview only',
                'color' => 'info',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Dry run'],
                'notes' => 'The item was only simulated and not applied.',
            ],
            'mapped' => [
                'axis' => 'item_result',
                'label' => 'Mapped to existing item',
                'color' => 'info',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Mapped'],
                'notes' => 'The source item mapped to an existing target.',
            ],
            'skipped' => [
                'axis' => 'item_result',
                'label' => 'Not applied',
                'color' => 'gray',
                'classification' => 'primary',
                'next_action_policy' => 'optional',
                'legacy_aliases' => ['Skipped'],
                'notes' => 'The item was intentionally not applied.',
            ],
            'partial' => [
                'axis' => 'item_result',
                'label' => 'Partially applied',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'optional',
                'legacy_aliases' => ['Partial'],
                'notes' => 'The item only applied in part and needs review.',
            ],
            'manual_required' => [
                'axis' => 'operator_actionability',
                'label' => 'Manual follow-up needed',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Manual required'],
                'notes' => 'The operator must handle this item manually.',
            ],
            'failed' => [
                'axis' => 'item_result',
                'label' => 'Apply failed',
                'color' => 'danger',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Failed'],
                'notes' => 'The item failed to apply.',
            ],
        ],
        'restore_preview_decision' => [
            'created' => [
                'axis' => 'item_result',
                'label' => 'Will create',
                'color' => 'success',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Created'],
                'notes' => 'The preview plans to create a new target item.',
            ],
            'created_copy' => [
                'axis' => 'item_result',
                'label' => 'Will create copy',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'optional',
                'legacy_aliases' => ['Created copy'],
                'notes' => 'The preview plans to create a copy and should be reviewed before execution.',
            ],
            'mapped_existing' => [
                'axis' => 'item_result',
                'label' => 'Will map existing',
                'color' => 'info',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Mapped existing'],
                'notes' => 'The preview plans to map this item to an existing target.',
            ],
            'skipped' => [
                'axis' => 'item_result',
                'label' => 'Will skip',
                'color' => 'gray',
                'classification' => 'primary',
                'next_action_policy' => 'optional',
                'legacy_aliases' => ['Skipped'],
                'notes' => 'The preview plans to skip this item.',
            ],
            'failed' => [
                'axis' => 'item_result',
                'label' => 'Cannot apply',
                'color' => 'danger',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Failed'],
                'notes' => 'The preview could not produce a viable action for this item.',
            ],
        ],
        'restore_check_severity' => [
            'blocking' => [
                'axis' => 'operator_actionability',
                'label' => 'Fix before running',
                'color' => 'danger',
                'classification' => 'primary',
                'next_action_policy' => 'required',
                'legacy_aliases' => ['Blocking'],
                'notes' => 'Execution should not proceed until this check is fixed.',
            ],
            'warning' => [
                'axis' => 'operator_actionability',
                'label' => 'Review before running',
                'color' => 'warning',
                'classification' => 'primary',
                'next_action_policy' => 'optional',
                'legacy_aliases' => ['Warning'],
                'notes' => 'Execution may proceed, but the operator should review the warning first.',
            ],
            'safe' => [
                'axis' => 'operator_actionability',
                'label' => 'Ready to continue',
                'color' => 'success',
                'classification' => 'primary',
                'next_action_policy' => 'none',
                'legacy_aliases' => ['Safe'],
                'notes' => 'No blocking issue was found for this check.',
            ],
        ],
    ];

    /**
     * @return array{
     *     axis: OperatorSemanticAxis,
     *     label: string,
     *     color: string,
     *     classification: OperatorStateClassification,
     *     next_action_policy: OperatorNextActionPolicy,
     *     legacy_aliases: list<string>,
     *     diagnostic_label: ?string,
     *     notes: string
     * }|null
     */
    public static function entry(BadgeDomain $domain, mixed $value): ?array
    {
        $state = BadgeCatalog::normalizeState($value);

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

        if ($domain === BadgeDomain::OperationRunOutcome && $state === 'operation.blocked') {
            $state = 'blocked';
        }

        $entry = self::ENTRIES[$domain->value][$state] ?? null;

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

        return [
            'axis' => self::axisFrom($entry['axis']),
            'label' => $entry['label'],
            'color' => $entry['color'],
            'classification' => self::classificationFrom($entry['classification']),
            'next_action_policy' => self::nextActionPolicyFrom($entry['next_action_policy']),
            'legacy_aliases' => $entry['legacy_aliases'],
            'diagnostic_label' => $entry['diagnostic_label'] ?? null,
            'notes' => $entry['notes'],
        ];
    }

    /**
     * @return array<string, array<string, array{
     *     axis: OperatorSemanticAxis,
     *     label: string,
     *     color: string,
     *     classification: OperatorStateClassification,
     *     next_action_policy: OperatorNextActionPolicy,
     *     legacy_aliases: list<string>,
     *     diagnostic_label: ?string,
     *     notes: string
     * }>>
     */
    public static function all(): array
    {
        $entries = [];

        foreach (self::ENTRIES as $domain => $mappings) {
            foreach ($mappings as $state => $entry) {
                $entries[$domain][$state] = [
                    'axis' => self::axisFrom($entry['axis']),
                    'label' => $entry['label'],
                    'color' => $entry['color'],
                    'classification' => self::classificationFrom($entry['classification']),
                    'next_action_policy' => self::nextActionPolicyFrom($entry['next_action_policy']),
                    'legacy_aliases' => $entry['legacy_aliases'],
                    'diagnostic_label' => $entry['diagnostic_label'] ?? null,
                    'notes' => $entry['notes'],
                ];
            }
        }

        return $entries;
    }

    /**
     * @return list<array{name: string, domain: BadgeDomain, raw_value: string}>
     */
    public static function curatedExamples(): array
    {
        return [
            ['name' => 'Operation blocked by missing prerequisite', 'domain' => BadgeDomain::OperationRunOutcome, 'raw_value' => 'blocked'],
            ['name' => 'Artifact exists but is not usable', 'domain' => BadgeDomain::GovernanceArtifactExistence, 'raw_value' => 'created_but_not_usable'],
            ['name' => 'Artifact is trustworthy', 'domain' => BadgeDomain::GovernanceArtifactContent, 'raw_value' => 'trusted'],
            ['name' => 'Artifact is stale', 'domain' => BadgeDomain::GovernanceArtifactFreshness, 'raw_value' => 'stale'],
            ['name' => 'Artifact is publishable', 'domain' => BadgeDomain::GovernanceArtifactPublicationReadiness, 'raw_value' => 'publishable'],
            ['name' => 'Artifact requires action', 'domain' => BadgeDomain::GovernanceArtifactActionability, 'raw_value' => 'required'],
            ['name' => 'Operation completed with follow-up', 'domain' => BadgeDomain::OperationRunOutcome, 'raw_value' => 'partially_succeeded'],
            ['name' => 'Operation completed successfully', 'domain' => BadgeDomain::OperationRunOutcome, 'raw_value' => 'succeeded'],
            ['name' => 'Evidence not collected yet', 'domain' => BadgeDomain::EvidenceCompleteness, 'raw_value' => 'missing'],
            ['name' => 'Evidence refresh recommended', 'domain' => BadgeDomain::EvidenceCompleteness, 'raw_value' => 'stale'],
            ['name' => 'Review input pending', 'domain' => BadgeDomain::EnvironmentReviewCompleteness, 'raw_value' => 'missing'],
            ['name' => 'Mixed evidence detail stays diagnostic', 'domain' => BadgeDomain::BaselineSnapshotFidelity, 'raw_value' => 'partial'],
            ['name' => 'Support limited stays diagnostic', 'domain' => BadgeDomain::BaselineSnapshotFidelity, 'raw_value' => 'unsupported'],
            ['name' => 'Coverage gaps need review', 'domain' => BadgeDomain::BaselineSnapshotGapStatus, 'raw_value' => 'gaps_present'],
            ['name' => 'Restore preview blocked by a check', 'domain' => BadgeDomain::RestoreCheckSeverity, 'raw_value' => 'blocking'],
            ['name' => 'Restore run applied with follow-up', 'domain' => BadgeDomain::RestoreRunStatus, 'raw_value' => 'completed_with_errors'],
            ['name' => 'Restore item requires manual follow-up', 'domain' => BadgeDomain::RestoreResultStatus, 'raw_value' => 'manual_required'],
        ];
    }

    public static function spec(
        BadgeDomain $domain,
        mixed $value,
        ?string $icon = null,
        ?string $iconColor = null,
    ): ?BadgeSpec {
        $entry = self::entry($domain, $value);

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

        return new BadgeSpec(
            label: $entry['label'],
            color: $entry['color'],
            icon: $icon,
            iconColor: $iconColor,
            semanticAxis: $entry['axis'],
            classification: $entry['classification'],
            nextActionPolicy: $entry['next_action_policy'],
            diagnosticLabel: $entry['diagnostic_label'],
            legacyAliases: $entry['legacy_aliases'],
            notes: $entry['notes'],
        );
    }

    private static function axisFrom(string $value): OperatorSemanticAxis
    {
        return OperatorSemanticAxis::tryFrom($value)
            ?? throw new InvalidArgumentException("Unknown operator semantic axis [{$value}].");
    }

    private static function classificationFrom(string $value): OperatorStateClassification
    {
        return OperatorStateClassification::tryFrom($value)
            ?? throw new InvalidArgumentException("Unknown operator state classification [{$value}].");
    }

    private static function nextActionPolicyFrom(string $value): OperatorNextActionPolicy
    {
        return OperatorNextActionPolicy::tryFrom($value)
            ?? throw new InvalidArgumentException("Unknown operator next-action policy [{$value}].");
    }
}
