<?php

declare(strict_types=1);

namespace App\Support\Operations;

use App\Support\ReasonTranslation\NextStepOption;
use App\Support\ReasonTranslation\PlatformReasonFamily;
use App\Support\ReasonTranslation\ReasonOwnershipDescriptor;
use App\Support\ReasonTranslation\ReasonResolutionEnvelope;

enum LifecycleReconciliationReason: string
{
    case StaleQueued = 'run.stale_queued';
    case StaleRunning = 'run.stale_running';
    case InfrastructureTimeoutOrAbandonment = 'run.infrastructure_timeout_or_abandonment';
    case QueueFailureBridge = 'run.queue_failure_bridge';
    case AdapterOutOfSync = 'run.adapter_out_of_sync';

    public function operatorLabel(): string
    {
        return match ($this) {
            self::StaleQueued => 'Run never started',
            self::StaleRunning => 'Run stopped reporting progress',
            self::InfrastructureTimeoutOrAbandonment => 'Infrastructure ended the run',
            self::QueueFailureBridge => 'Queue failure was reconciled',
            self::AdapterOutOfSync => 'Lifecycle was reconciled from related records',
        };
    }

    public function shortExplanation(): string
    {
        return match ($this) {
            self::StaleQueued => 'The run stayed queued past its lifecycle window and was marked failed.',
            self::StaleRunning => 'The run stayed active past its lifecycle window and was marked failed.',
            self::InfrastructureTimeoutOrAbandonment => 'Queue infrastructure ended the job before normal completion could update the run.',
            self::QueueFailureBridge => 'The platform bridged a queue failure back to the owning run and marked it failed.',
            self::AdapterOutOfSync => 'A related restore record reached terminal truth before the operation run was updated.',
        };
    }

    public function actionability(): string
    {
        return match ($this) {
            self::AdapterOutOfSync => 'non_actionable',
            default => 'retryable_transient',
        };
    }

    /**
     * @return array<int, NextStepOption>
     */
    public function nextSteps(): array
    {
        return match ($this) {
            self::AdapterOutOfSync => [
                NextStepOption::instruction('Review the related restore record before deciding whether to run the workflow again.'),
            ],
            default => [
                NextStepOption::instruction('Review worker health and logs before retrying this operation.'),
            ],
        };
    }

    public function defaultMessage(): string
    {
        return $this->shortExplanation();
    }

    /**
     * @param  array<string, mixed>  $context
     */
    public function toReasonResolutionEnvelope(string $surface = 'detail', array $context = []): ReasonResolutionEnvelope
    {
        return new ReasonResolutionEnvelope(
            internalCode: $this->value,
            operatorLabel: $this->operatorLabel(),
            shortExplanation: $this->shortExplanation(),
            actionability: $this->actionability(),
            nextSteps: $this->nextSteps(),
            showNoActionNeeded: false,
            diagnosticCodeLabel: $this->value,
            reasonOwnership: new ReasonOwnershipDescriptor(
                ownerLayer: 'platform_core',
                ownerNamespace: 'operation_lifecycle',
                reasonCode: $this->value,
                platformReasonFamily: PlatformReasonFamily::Execution,
            ),
        );
    }
}
