<?php

namespace Database\Seeders;

use Carbon\Carbon;
use App\Models\Draw;
use App\Lottery\DrawStatus;
use App\Models\DrawResultItem;
use App\Models\DrawResultBatch;
use Illuminate\Database\Seeder;
use App\Lottery\DrawResultBatchStatus;
use App\Services\Draw\DrawPrizeLayout;

/**
 * 【本地演示】写入若干条 `draws` + 一条带完整 23 组开奖，便于前端大厅 / 开奖结果联调。
 *
 * - 一页「当期」：**open**，封盘时间晚于此刻，玩家在 `/hall` 可见倒计时。
 * - 一条 **pending**（将来期）排在后面。
 * - 一条 **settled**（已结算）附 `draw_result_batches` / `draw_result_items`，`/api/v1/draw/results` 有数据。
 *
 * ```bash
 * php artisan db:seed --class="Database\\Seeders\\DrawDemoSeeder"
 * ```
 */
final class DrawDemoSeeder extends Seeder
{
    public function run(): void
    {
        $now = Carbon::now()->utc();
        $biz = $now->format('Y-m-d');
        $ymdCompact = str_replace('-', '', $biz);

        $this->seedFinishedDrawForResults($biz, $ymdCompact, $now);
        $this->seedCurrentOpenDraw($biz, $ymdCompact, $now);
        $this->seedFuturePendingDraw($biz, $ymdCompact, $now);
    }

    private function seedFinishedDrawForResults(string $biz, string $ymdCompact, Carbon $now): void
    {
        $drawTime = $now->copy()->subHours(3);

        $draw = Draw::query()->updateOrCreate(
            ['draw_no' => $ymdCompact.'-801'],
            [
                'business_date' => $biz,
                'sequence_no' => 801,
                'status' => DrawStatus::Settled->value,
                'start_time' => $drawTime->copy()->subMinutes(30),
                'close_time' => $drawTime->copy()->subSeconds(30),
                'draw_time' => $drawTime,
                'cooling_end_time' => $drawTime->copy()->addMinutes(15),
                'result_source' => 'rng',
                'current_result_version' => 1,
                'settle_version' => 1,
                'is_reopened' => false,
            ],
        );

        $batch = DrawResultBatch::query()->updateOrCreate(
            [
                'draw_id' => $draw->id,
                'result_version' => 1,
            ],
            [
                'source_type' => 'rng',
                'rng_seed_hash' => hash('sha256', 'demo-draw-801-seed'),
                'raw_seed_encrypted' => null,
                'status' => DrawResultBatchStatus::Published->value,
                'created_by' => null,
                'confirmed_by' => null,
                'confirmed_at' => $drawTime,
            ],
        );

        DrawResultItem::query()->where('result_batch_id', $batch->id)->delete();

        foreach (DrawPrizeLayout::slots() as $i => $slot) {
            $n = (($i + 1) * 409) % 10_000;
            $num = str_pad((string) $n, 4, '0', STR_PAD_LEFT);
            DrawResultItem::query()->create([
                'draw_id' => $draw->id,
                'result_batch_id' => $batch->id,
                'prize_type' => $slot['prize_type'],
                'prize_index' => $slot['prize_index'],
                'number_4d' => $num,
                'suffix_3d' => substr($num, -3),
                'suffix_2d' => substr($num, -2),
                'head_digit' => (int) substr($num, 0, 1),
                'tail_digit' => (int) substr($num, 3, 1),
            ]);
        }
    }

    private function seedCurrentOpenDraw(string $biz, string $ymdCompact, Carbon $now): void
    {
        $drawTime = $now->copy()->addMinutes(20);

        Draw::query()->updateOrCreate(
            ['draw_no' => $ymdCompact.'-802'],
            [
                'business_date' => $biz,
                'sequence_no' => 802,
                'status' => DrawStatus::Open->value,
                'start_time' => $now->copy()->subMinutes(5),
                'close_time' => $drawTime->copy()->subSeconds(30),
                'draw_time' => $drawTime,
                'cooling_end_time' => null,
                'result_source' => null,
                'current_result_version' => 0,
                'settle_version' => 0,
                'is_reopened' => false,
            ],
        );
    }

    private function seedFuturePendingDraw(string $biz, string $ymdCompact, Carbon $now): void
    {
        $start = $now->copy()->addMinutes(55);
        $close = $start->copy()->addMinutes(12);
        $draw = $close->copy()->addSeconds(30);

        Draw::query()->updateOrCreate(
            ['draw_no' => $ymdCompact.'-803'],
            [
                'business_date' => $biz,
                'sequence_no' => 803,
                'status' => DrawStatus::Pending->value,
                'start_time' => $start,
                'close_time' => $close,
                'draw_time' => $draw,
                'cooling_end_time' => null,
                'result_source' => null,
                'current_result_version' => 0,
                'settle_version' => 0,
                'is_reopened' => false,
            ],
        );
    }
}
