<?php

declare(strict_types=1);

namespace App\Support\Ui\GovernanceArtifactTruth;

use InvalidArgumentException;

final readonly class SurfaceCompressionContext
{
    /**
     * @param  list<string>  $primaryDimensionPriority
     * @param  list<string>  $secondaryDimensions
     */
    public function __construct(
        public string $surfaceFamily,
        public string $decisionRole,
        public string $primaryQuestion,
        public array $primaryDimensionPriority,
        public array $secondaryDimensions,
        public bool $diagnosticsAllowed,
        public string $canonicalNoun,
    ) {
        if (trim($this->surfaceFamily) === '') {
            throw new InvalidArgumentException('Surface compression contexts require a surface family.');
        }

        if (trim($this->decisionRole) === '') {
            throw new InvalidArgumentException('Surface compression contexts require a decision role.');
        }

        if (trim($this->primaryQuestion) === '') {
            throw new InvalidArgumentException('Surface compression contexts require a primary question.');
        }

        if (trim($this->canonicalNoun) === '') {
            throw new InvalidArgumentException('Surface compression contexts require a canonical noun.');
        }
    }

    public static function baselineSnapshot(): self
    {
        return self::fromSurfaceFamily('baseline_snapshot');
    }

    public static function evidenceSnapshot(): self
    {
        return self::fromSurfaceFamily('evidence_snapshot');
    }

    public static function environmentReview(): self
    {
        return self::fromSurfaceFamily('environment_review');
    }

    public static function reviewPack(): self
    {
        return self::fromSurfaceFamily('review_pack');
    }

    public static function reviewRegister(): self
    {
        return self::fromSurfaceFamily('review_register');
    }

    public static function evidenceOverview(): self
    {
        return self::fromSurfaceFamily('evidence_overview');
    }

    public static function operationRunArtifact(): self
    {
        return self::fromSurfaceFamily('operation_run_artifact');
    }

    public static function defaultForArtifactFamily(string $artifactFamily): self
    {
        return match ($artifactFamily) {
            'baseline_snapshot' => self::baselineSnapshot(),
            'evidence_snapshot' => self::evidenceSnapshot(),
            'environment_review' => self::environmentReview(),
            'review_pack' => self::reviewPack(),
            'artifact_run' => self::operationRunArtifact(),
            default => throw new InvalidArgumentException(sprintf('No default compression context exists for artifact family [%s].', $artifactFamily)),
        };
    }

    public static function fromSurfaceFamily(string $surfaceFamily): self
    {
        return match (trim($surfaceFamily)) {
            'baseline_snapshot' => new self(
                surfaceFamily: 'baseline_snapshot',
                decisionRole: 'secondary_context',
                primaryQuestion: 'Is this baseline artifact usable right now?',
                primaryDimensionPriority: ['content_fidelity', 'data_freshness', 'artifact_existence'],
                secondaryDimensions: ['data_freshness', 'artifact_existence', 'operator_actionability'],
                diagnosticsAllowed: true,
                canonicalNoun: 'Baseline snapshot',
            ),
            'evidence_snapshot' => new self(
                surfaceFamily: 'evidence_snapshot',
                decisionRole: 'secondary_context',
                primaryQuestion: 'Is this evidence basis usable now?',
                primaryDimensionPriority: ['content_fidelity', 'data_freshness', 'artifact_existence'],
                secondaryDimensions: ['data_freshness', 'content_fidelity', 'operator_actionability'],
                diagnosticsAllowed: true,
                canonicalNoun: 'Evidence snapshot',
            ),
            'environment_review' => new self(
                surfaceFamily: 'environment_review',
                decisionRole: 'primary_decision',
                primaryQuestion: 'Is this review ready for real use or publication?',
                primaryDimensionPriority: ['publication_readiness', 'data_freshness', 'content_fidelity'],
                secondaryDimensions: ['publication_readiness', 'data_freshness', 'content_fidelity', 'operator_actionability'],
                diagnosticsAllowed: true,
                canonicalNoun: 'Review',
            ),
            'review_pack' => new self(
                surfaceFamily: 'review_pack',
                decisionRole: 'primary_decision',
                primaryQuestion: 'Can this pack be shared externally?',
                primaryDimensionPriority: ['publication_readiness', 'data_freshness', 'content_fidelity'],
                secondaryDimensions: ['publication_readiness', 'data_freshness', 'content_fidelity', 'operator_actionability'],
                diagnosticsAllowed: true,
                canonicalNoun: 'Review pack',
            ),
            'review_register' => new self(
                surfaceFamily: 'review_register',
                decisionRole: 'primary_decision',
                primaryQuestion: 'Which reviews need immediate follow-up?',
                primaryDimensionPriority: ['publication_readiness', 'data_freshness', 'content_fidelity'],
                secondaryDimensions: ['data_freshness', 'content_fidelity'],
                diagnosticsAllowed: false,
                canonicalNoun: 'Review',
            ),
            'evidence_overview' => new self(
                surfaceFamily: 'evidence_overview',
                decisionRole: 'secondary_context',
                primaryQuestion: 'Which tenants have usable evidence now?',
                primaryDimensionPriority: ['content_fidelity', 'data_freshness', 'artifact_existence'],
                secondaryDimensions: ['data_freshness', 'content_fidelity'],
                diagnosticsAllowed: false,
                canonicalNoun: 'Evidence snapshot',
            ),
            'operation_run_artifact' => new self(
                surfaceFamily: 'operation_run_artifact',
                decisionRole: 'tertiary_evidence',
                primaryQuestion: 'Why did this run leave the related artifact in this state?',
                primaryDimensionPriority: ['publication_readiness', 'content_fidelity', 'data_freshness', 'artifact_existence'],
                secondaryDimensions: ['artifact_existence', 'data_freshness', 'content_fidelity', 'publication_readiness'],
                diagnosticsAllowed: true,
                canonicalNoun: 'Operation run',
            ),
            default => throw new InvalidArgumentException(sprintf('Unsupported surface compression family [%s].', $surfaceFamily)),
        };
    }

    public function cacheVariant(): string
    {
        return 'compressed_governance_outcome:'.$this->surfaceFamily;
    }

    public function prioritizesPublication(): bool
    {
        return in_array('publication_readiness', $this->primaryDimensionPriority, true);
    }
}
