<?php

namespace App\Services\Draw;

use Carbon\Carbon;
use App\Lottery\DrawStatus;
use App\Services\LotterySettings;

/**
 * 由开奖时刻推导下注窗口、封盘时刻与期号初始状态。
 */
final class DrawTimelineBuilder
{
    public function closeBeforeDrawSeconds(): int
    {
        return LotterySettings::drawCloseBeforeDrawSeconds();
    }

    public function bettingWindowSeconds(): int
    {
        return LotterySettings::drawBettingWindowSeconds();
    }

    /**
     * @return array{start_local: Carbon, close_local: Carbon, draw_local: Carbon}
     */
    public function windowsFromDrawLocal(Carbon $drawLocal): array
    {
        $closeLocal = $drawLocal->copy()->subSeconds($this->closeBeforeDrawSeconds());
        $startLocal = $closeLocal->copy()->subSeconds($this->bettingWindowSeconds());

        return [
            'start_local' => $startLocal,
            'close_local' => $closeLocal,
            'draw_local' => $drawLocal->copy(),
        ];
    }

    /**
     * @return array{start_utc: Carbon, close_utc: Carbon, draw_utc: Carbon, status: string}
     */
    public function buildFromLocals(Carbon $startLocal, Carbon $closeLocal, Carbon $drawLocal, Carbon $nowUtc): array
    {
        $startUtc = $startLocal->copy()->timezone('UTC');
        $closeUtc = $closeLocal->copy()->timezone('UTC');
        $drawUtc = $drawLocal->copy()->timezone('UTC');

        return [
            'start_utc' => $startUtc,
            'close_utc' => $closeUtc,
            'draw_utc' => $drawUtc,
            'status' => $this->statusForTimeline($nowUtc, $startUtc, $closeUtc, $drawUtc),
        ];
    }

    public function statusForTimeline(Carbon $nowUtc, Carbon $startUtc, Carbon $closeUtc, Carbon $drawUtc): string
    {
        if ($nowUtc < $startUtc) {
            return DrawStatus::Pending->value;
        }
        if ($nowUtc < $closeUtc) {
            return DrawStatus::Open->value;
        }
        if ($nowUtc < $drawUtc) {
            return DrawStatus::Closing->value;
        }

        return DrawStatus::Closed->value;
    }

    public function drawNo(string $businessDate, int $sequenceNo): string
    {
        return str_replace('-', '', $businessDate).'-'.
            str_pad((string) $sequenceNo, 3, '0', STR_PAD_LEFT);
    }
}
