<?php

namespace App\Console\Commands;

use App\Models\Draw;
use Illuminate\Console\Command;
use App\Services\Draw\DrawTickService;
use Illuminate\Support\Facades\DB;

/**
 * 开发/测试库：按营业日区间删除积压期号（级联清理关联数据）。
 *
 * 仅允许 local / testing 环境执行。
 */
final class LotteryDevPruneDrawBacklogCommand extends Command
{
    protected $signature = 'lottery:dev-prune-draw-backlog
                            {--from=2026-05-11 : 营业日起（Y-m-d）}
                            {--to=2026-05-22 : 营业日止（Y-m-d）}
                            {--dry-run : 只统计，不删除}
                            {--force : 跳过确认}
                            {--tick : 删除后执行 lottery:draw-tick（积压多时可能占内存）}';

    protected $description = '【仅 dev/test】删除指定营业日区间的期号积压（cascade）';

    public function handle(DrawTickService $tickService): int
    {
        if (! app()->environment(['local', 'testing'])) {
            $this->error('Refused: only allowed in local or testing environment.');

            return self::FAILURE;
        }

        $from = (string) $this->option('from');
        $to = (string) $this->option('to');
        $dryRun = (bool) $this->option('dry-run');

        $query = Draw::query()->whereBetween('business_date', [$from, $to]);
        $total = (int) $query->count();

        if ($total === 0) {
            $this->info("No draws found between {$from} and {$to}.");

            return self::SUCCESS;
        }

        $byStatus = (clone $query)
            ->selectRaw('status, count(*) as c')
            ->groupBy('status')
            ->orderByDesc('c')
            ->pluck('c', 'status');

        $drawIds = (clone $query)->pluck('id');
        $ticketOrders = (int) DB::table('ticket_orders')->whereIn('draw_id', $drawIds)->count();

        $this->table(
            ['Metric', 'Value'],
            [
                ['Date range', "{$from} .. {$to}"],
                ['Draws to delete', (string) $total],
                ['Ticket orders (cascade)', (string) $ticketOrders],
            ],
        );

        $this->line('By status:');
        foreach ($byStatus as $status => $count) {
            $this->line("  {$status}: {$count}");
        }

        if ($dryRun) {
            $this->info('Dry run — no rows deleted.');

            return self::SUCCESS;
        }

        if (! $this->option('force') && ! $this->confirm("Delete {$total} draws and related rows?", false)) {
            $this->warn('Aborted.');

            return self::SUCCESS;
        }

        $deleted = 0;
        (clone $query)->orderBy('id')->chunkById(200, function ($draws) use (&$deleted): void {
            foreach ($draws as $draw) {
                $draw->delete();
                $deleted++;
            }
            $this->output->write('.');
        });

        $this->newLine();
        $this->info("Deleted {$deleted} draws.");

        if ($this->option('tick')) {
            $report = $tickService->tick();
            $this->info(sprintf(
                'Post-tick: status_updates=%d rng=%d planned_created=%d',
                array_sum($report['status_updates'] ?? []),
                $report['rng_rung'],
                $report['planned']['created'] ?? 0,
            ));
        } else {
            $this->comment('Skipped tick (pass --tick to run draw-tick after prune).');
        }

        $head = Draw::query()
            ->whereNotIn('status', ['settled', 'cancelled'])
            ->orderBy('draw_time')
            ->first(['draw_no', 'status', 'draw_time']);

        if ($head !== null) {
            $this->info("Hall pipeline head is now: {$head->draw_no} ({$head->status}) @ {$head->draw_time}");
        } else {
            $this->info('Hall pipeline head: none (all settled/cancelled).');
        }

        return self::SUCCESS;
    }
}
