<?php

declare(strict_types=1);

namespace App\Services\SupportCenter;

use App\Enums\SupportCenter\HostSystemUpdateExecutionStatus;
use App\Enums\SupportCenter\HostSystemUpdateExecutionStep;

/**
 * 更新执行状态、步骤与进度映射（显式规则，便于审计）。
 */
final class HostSystemUpdateExecutionStateCatalog
{
    /**
     * @return array<string, list<string>>
     */
    public static function allowedTransitions(): array
    {
        return [
            HostSystemUpdateExecutionStatus::Pending->value => [
                HostSystemUpdateExecutionStatus::Prechecking->value,
                HostSystemUpdateExecutionStatus::Cancelled->value,
            ],
            HostSystemUpdateExecutionStatus::Prechecking->value => [
                HostSystemUpdateExecutionStatus::Ready->value,
                HostSystemUpdateExecutionStatus::Failed->value,
                HostSystemUpdateExecutionStatus::Cancelled->value,
            ],
            HostSystemUpdateExecutionStatus::Ready->value => [
                HostSystemUpdateExecutionStatus::Running->value,
                HostSystemUpdateExecutionStatus::Failed->value,
                HostSystemUpdateExecutionStatus::Cancelled->value,
            ],
            HostSystemUpdateExecutionStatus::Running->value => [
                HostSystemUpdateExecutionStatus::Completed->value,
                HostSystemUpdateExecutionStatus::Failed->value,
                HostSystemUpdateExecutionStatus::RollbackRequired->value,
                HostSystemUpdateExecutionStatus::Cancelled->value,
            ],
            HostSystemUpdateExecutionStatus::RollbackRequired->value => [
                HostSystemUpdateExecutionStatus::RollingBack->value,
                HostSystemUpdateExecutionStatus::Failed->value,
            ],
            HostSystemUpdateExecutionStatus::RollingBack->value => [
                HostSystemUpdateExecutionStatus::RolledBack->value,
                HostSystemUpdateExecutionStatus::RollbackFailed->value,
                HostSystemUpdateExecutionStatus::Failed->value,
            ],
        ];
    }

    public static function canTransition(?string $fromStatus, string $toStatus): bool
    {
        if ($fromStatus === null || trim($fromStatus) === '') {
            return false;
        }

        $allowed = self::allowedTransitions()[$fromStatus] ?? [];

        return in_array($toStatus, $allowed, true);
    }

    public static function progressForStep(?string $step): int
    {
        return match ($step) {
            HostSystemUpdateExecutionStep::Created->value => 0,
            HostSystemUpdateExecutionStep::Precheck->value => 5,
            HostSystemUpdateExecutionStep::Backup->value => 10,
            HostSystemUpdateExecutionStep::MaintenanceDown->value => 15,
            HostSystemUpdateExecutionStep::ExtractStaging->value => 25,
            HostSystemUpdateExecutionStep::VerifyStaging->value => 35,
            HostSystemUpdateExecutionStep::ReplaceFiles->value => 50,
            HostSystemUpdateExecutionStep::ReplaceVendor->value => 60,
            HostSystemUpdateExecutionStep::RunMigrations->value => 70,
            HostSystemUpdateExecutionStep::ClearCache->value => 80,
            HostSystemUpdateExecutionStep::WriteVersion->value => 90,
            HostSystemUpdateExecutionStep::MaintenanceUp->value => 95,
            HostSystemUpdateExecutionStep::Completed->value => 100,
            default => 0,
        };
    }

    public static function defaultStepForStatus(string $status): ?string
    {
        return match ($status) {
            HostSystemUpdateExecutionStatus::Pending->value => HostSystemUpdateExecutionStep::Created->value,
            HostSystemUpdateExecutionStatus::Prechecking->value => HostSystemUpdateExecutionStep::Precheck->value,
            HostSystemUpdateExecutionStatus::Ready->value => HostSystemUpdateExecutionStep::Precheck->value,
            HostSystemUpdateExecutionStatus::Running->value => HostSystemUpdateExecutionStep::Backup->value,
            HostSystemUpdateExecutionStatus::Completed->value => HostSystemUpdateExecutionStep::Completed->value,
            HostSystemUpdateExecutionStatus::Failed->value => HostSystemUpdateExecutionStep::Failed->value,
            HostSystemUpdateExecutionStatus::Cancelled->value => HostSystemUpdateExecutionStep::Failed->value,
            HostSystemUpdateExecutionStatus::RollbackRequired->value,
            HostSystemUpdateExecutionStatus::RollingBack->value,
            HostSystemUpdateExecutionStatus::RolledBack->value,
            HostSystemUpdateExecutionStatus::RollbackFailed->value => HostSystemUpdateExecutionStep::Rollback->value,
            default => null,
        };
    }
}
