<?php

declare(strict_types=1);

namespace App\Support\Ui\GovernanceArtifactTruth;

use App\Support\ReasonTranslation\NextStepOption;
use App\Support\ReasonTranslation\PlatformReasonFamily;
use App\Support\ReasonTranslation\ReasonOwnershipDescriptor;
use App\Support\ReasonTranslation\ReasonResolutionEnvelope;
use App\Support\Ui\OperatorExplanation\TrustworthinessLevel;

final readonly class ArtifactTruthCause
{
    /**
     * @param  array<int, string>  $nextSteps
     */
    public function __construct(
        public ?string $reasonCode,
        public ?string $translationArtifact,
        public ?string $operatorLabel,
        public ?string $shortExplanation,
        public ?string $diagnosticCode,
        public ?string $actionability,
        public string $trustImpact,
        public ?string $absencePattern,
        public array $nextSteps = [],
        public ?string $ownerLayer = null,
        public ?string $ownerNamespace = null,
        public ?string $platformReasonFamily = null,
    ) {}

    public static function fromReasonResolutionEnvelope(
        ?ReasonResolutionEnvelope $reason,
        ?string $translationArtifact = null,
    ): ?self {
        if (! $reason instanceof ReasonResolutionEnvelope) {
            return null;
        }

        return new self(
            reasonCode: $reason->internalCode,
            translationArtifact: $translationArtifact,
            operatorLabel: $reason->operatorLabel,
            shortExplanation: $reason->shortExplanation,
            diagnosticCode: $reason->diagnosticCode(),
            actionability: $reason->actionability,
            trustImpact: $reason->trustImpact,
            absencePattern: $reason->absencePattern,
            nextSteps: array_values(array_map(
                static fn (NextStepOption $nextStep): string => $nextStep->label,
                $reason->nextSteps,
            )),
            ownerLayer: $reason->ownerLayer(),
            ownerNamespace: $reason->ownerNamespace(),
            platformReasonFamily: $reason->platformReasonFamily(),
        );
    }

    public function toReasonResolutionEnvelope(): ReasonResolutionEnvelope
    {
        $reasonOwnership = null;
        $family = is_string($this->platformReasonFamily)
            ? PlatformReasonFamily::tryFrom($this->platformReasonFamily)
            : null;

        if (is_string($this->ownerLayer)
            && trim($this->ownerLayer) !== ''
            && is_string($this->ownerNamespace)
            && trim($this->ownerNamespace) !== ''
            && $family instanceof PlatformReasonFamily) {
            $reasonOwnership = new ReasonOwnershipDescriptor(
                ownerLayer: trim($this->ownerLayer),
                ownerNamespace: trim($this->ownerNamespace),
                reasonCode: $this->reasonCode ?? 'artifact_truth_reason',
                platformReasonFamily: $family,
            );
        }

        return new ReasonResolutionEnvelope(
            internalCode: $this->reasonCode ?? 'artifact_truth_reason',
            operatorLabel: $this->operatorLabel ?? 'Operator attention required',
            shortExplanation: $this->shortExplanation ?? 'Technical diagnostics are available for this result.',
            actionability: $this->actionability
                ?? ($this->absencePattern === 'true_no_result' ? 'non_actionable' : 'prerequisite_missing'),
            nextSteps: array_map(
                static fn (string $label): NextStepOption => NextStepOption::instruction($label),
                $this->nextSteps,
            ),
            diagnosticCodeLabel: $this->diagnosticCode,
            trustImpact: $this->trustImpact !== '' ? $this->trustImpact : TrustworthinessLevel::LimitedConfidence->value,
            absencePattern: $this->absencePattern,
            reasonOwnership: $reasonOwnership,
        );
    }

    /**
     * @return array{
     *     reasonCode: ?string,
     *     translationArtifact: ?string,
     *     operatorLabel: ?string,
     *     shortExplanation: ?string,
     *     diagnosticCode: ?string,
     *     actionability: ?string,
     *     trustImpact: string,
     *     absencePattern: ?string,
     *     nextSteps: array<int, string>,
     *     ownerLayer: ?string,
     *     ownerNamespace: ?string,
     *     platformReasonFamily: ?string
     * }
     */
    public function toArray(): array
    {
        return [
            'reasonCode' => $this->reasonCode,
            'translationArtifact' => $this->translationArtifact,
            'operatorLabel' => $this->operatorLabel,
            'shortExplanation' => $this->shortExplanation,
            'diagnosticCode' => $this->diagnosticCode,
            'actionability' => $this->actionability,
            'trustImpact' => $this->trustImpact,
            'absencePattern' => $this->absencePattern,
            'nextSteps' => $this->nextSteps,
            'ownerLayer' => $this->ownerLayer,
            'ownerNamespace' => $this->ownerNamespace,
            'platformReasonFamily' => $this->platformReasonFamily,
        ];
    }
}
