<?php

declare(strict_types=1);

/**
 * 本文件属于 DBErp 进销存系统。
 *
 * 版权所有 © 2026 北京珑大钜商科技有限公司。保留所有权利。
 *
 * 未经官方授权，不得删除、篡改或隐藏本文件中的版权声明、产品标识与来源信息。
 * 商业授权、官方更新与技术支持服务，请以珑大官方支持中心记录为准。
 *
 * @link https://support.loongdom.cn
 * @see  https://www.dberp.com.cn
 */

namespace App\Services\SupportCenter;

use App\Enums\SupportCenter\HostSystemUpdateExecutionStatus;
use App\Enums\SupportCenter\HostSystemUpdateExecutionStep;
use App\Enums\SupportCenter\HostSystemUpdateStepPhase;
use App\Models\HostSystemUpdateExecution;

/**
 * 将既有执行任务状态映射为 {@see HostSystemUpdateStepRunner} 可续跑的分步阶段。
 */
final class HostSystemUpdateExecutionResumePhaseResolver
{
    public function __construct(
        private readonly HostSystemUpdateMigrationBatchRunner $migrationBatchRunner,
        private readonly HostSystemUpdateBatchPhaseRunner $batchPhaseRunner,
    ) {}

    public function resolve(HostSystemUpdateExecution $execution): HostSystemUpdateExecutionResumeState
    {
        $step = HostSystemUpdateExecutionStep::tryFrom((string) ($execution->current_step ?? ''));
        $status = HostSystemUpdateExecutionStatus::tryFrom((string) ($execution->status ?? ''));

        $phase = $this->resolvePhase($status, $step);

        if ($phase === HostSystemUpdateStepPhase::MigrateBatch) {
            $execution = $execution->fresh(['package']) ?? $execution;

            return new HostSystemUpdateExecutionResumeState(
                phase: HostSystemUpdateStepPhase::MigrateBatch,
                migrationProgress: $this->migrationBatchRunner->snapshotProgress($execution),
                migratePhaseComplete: false,
            );
        }

        if ($this->isBatchablePhase($phase)) {
            $batchProgress = $this->batchPhaseRunner->snapshotProgress($execution, $phase);

            if ($batchProgress !== null && ! $batchProgress->isCompleted()) {
                return new HostSystemUpdateExecutionResumeState(
                    phase: $phase,
                    batchProgress: $batchProgress,
                );
            }
        }

        return new HostSystemUpdateExecutionResumeState(phase: $phase);
    }

    private function isBatchablePhase(HostSystemUpdateStepPhase $phase): bool
    {
        return match ($phase) {
            HostSystemUpdateStepPhase::ExtractStaging,
            HostSystemUpdateStepPhase::Backup,
            HostSystemUpdateStepPhase::ReplaceFiles,
            HostSystemUpdateStepPhase::ReplaceVendor => true,
            default => false,
        };
    }

    private function resolvePhase(
        ?HostSystemUpdateExecutionStatus $status,
        ?HostSystemUpdateExecutionStep $step,
    ): HostSystemUpdateStepPhase {
        if ($step !== null) {
            $fromStep = $this->phaseFromExecutionStep($status, $step);

            if ($fromStep !== null) {
                return $fromStep;
            }
        }

        return match ($status) {
            HostSystemUpdateExecutionStatus::Pending,
            HostSystemUpdateExecutionStatus::Prechecking => HostSystemUpdateStepPhase::Precheck,
            HostSystemUpdateExecutionStatus::Ready => HostSystemUpdateStepPhase::MaintenanceDown,
            default => HostSystemUpdateStepPhase::MaintenanceDown,
        };
    }

    private function phaseFromExecutionStep(
        ?HostSystemUpdateExecutionStatus $status,
        HostSystemUpdateExecutionStep $step,
    ): ?HostSystemUpdateStepPhase {
        return match ($step) {
            HostSystemUpdateExecutionStep::Created => HostSystemUpdateStepPhase::Precheck,
            HostSystemUpdateExecutionStep::Precheck => in_array($status, [
                HostSystemUpdateExecutionStatus::Ready,
                HostSystemUpdateExecutionStatus::Running,
            ], true)
                ? HostSystemUpdateStepPhase::MaintenanceDown
                : HostSystemUpdateStepPhase::Precheck,
            HostSystemUpdateExecutionStep::MaintenanceDown => HostSystemUpdateStepPhase::ExtractStaging,
            HostSystemUpdateExecutionStep::ExtractStaging,
            HostSystemUpdateExecutionStep::VerifyStaging => HostSystemUpdateStepPhase::ExtractStaging,
            HostSystemUpdateExecutionStep::Backup => HostSystemUpdateStepPhase::Backup,
            HostSystemUpdateExecutionStep::ReplaceFiles => HostSystemUpdateStepPhase::ReplaceFiles,
            HostSystemUpdateExecutionStep::ReplaceVendor => HostSystemUpdateStepPhase::ReplaceVendor,
            HostSystemUpdateExecutionStep::ResetRuntime => HostSystemUpdateStepPhase::ResetRuntime,
            HostSystemUpdateExecutionStep::ClearBootstrapCache => HostSystemUpdateStepPhase::ClearBootstrapCache,
            HostSystemUpdateExecutionStep::RuntimeReadiness => HostSystemUpdateStepPhase::RuntimeReadiness,
            HostSystemUpdateExecutionStep::RunMigrations => HostSystemUpdateStepPhase::MigrateBatch,
            HostSystemUpdateExecutionStep::ClearCache => HostSystemUpdateStepPhase::ClearCache,
            HostSystemUpdateExecutionStep::PostUpdateHealthCheck => HostSystemUpdateStepPhase::PostUpdateHealthCheck,
            HostSystemUpdateExecutionStep::WriteVersion => HostSystemUpdateStepPhase::WriteVersion,
            HostSystemUpdateExecutionStep::CommitVendorBackup => HostSystemUpdateStepPhase::CommitVendorBackup,
            HostSystemUpdateExecutionStep::MaintenanceUp => HostSystemUpdateStepPhase::Complete,
            default => null,
        };
    }
}
