<?php

declare(strict_types=1);

namespace App\Services\Install;

use Illuminate\Support\Str;

/**
 * 为分阶段 Web 安装创建 install_id、维护浏览器会话中的活动任务，并读写进度文件。
 */
final class WebInstallProgressSessionManager
{
    private const SESSION_KEY = 'dberp.web_install.active_install_id';

    public function __construct(
        private readonly WebInstallProgressStore $progressStore,
    ) {}

    /**
     * 创建新的安装会话并写入初始 pending 进度。
     */
    public function begin(): WebInstallProgressState
    {
        $installId = (string) Str::uuid();
        $state = $this->progressStore->createInitialState($installId);
        $this->rememberActiveInstallId($installId);

        return $state;
    }

    public function read(string $installId): ?WebInstallProgressState
    {
        return $this->progressStore->read($installId);
    }

    public function activeInstallId(): ?string
    {
        $installId = session(self::SESSION_KEY);

        if (! is_string($installId) || $installId === '') {
            return null;
        }

        if (! preg_match(
            '/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i',
            $installId,
        )) {
            return null;
        }

        return $installId;
    }

    public function rememberActiveInstallId(string $installId): void
    {
        session([self::SESSION_KEY => $installId]);
    }

    public function forgetActiveInstallId(): void
    {
        session()->forget(self::SESSION_KEY);
    }

    public function resolveActiveTask(): ?WebInstallProgressState
    {
        $installId = $this->activeInstallId();
        if ($installId === null) {
            return null;
        }

        $state = $this->read($installId);
        if ($state === null) {
            $this->forgetActiveInstallId();

            return null;
        }

        return $state;
    }

    public function cleanup(string $installId): bool
    {
        return $this->progressStore->delete($installId);
    }
}
