<?php

namespace App\Services\Draw;

use App\Models\Draw;
use App\Models\DrawResultBatch;
use App\Lottery\DrawStatus;
use Illuminate\Support\Facades\DB;
use App\Lottery\DrawResultBatchStatus;
use App\Models\SettlementBatch;

/**
 * 删除待审核开奖批次，便于作废草稿后重新录入或重新 RNG。
 */
final class DrawPendingResultBatchDiscardService
{
    public function discard(Draw $draw, DrawResultBatch $batch): Draw
    {
        return DB::transaction(function () use ($draw, $batch): Draw {
            /** @var DrawResultBatch $lockedBatch */
            $lockedBatch = DrawResultBatch::query()->whereKey($batch->id)->lockForUpdate()->firstOrFail();

            if ((int) $lockedBatch->draw_id !== (int) $draw->id) {
                throw new \RuntimeException('batch_draw_mismatch');
            }

            if ($lockedBatch->status !== DrawResultBatchStatus::PendingReview->value) {
                throw new \RuntimeException('batch_not_pending_review');
            }

            if (SettlementBatch::query()->where('result_batch_id', $lockedBatch->id)->exists()) {
                throw new \RuntimeException('batch_linked_to_settlement');
            }

            /** @var Draw $lockedDraw */
            $lockedDraw = Draw::query()->whereKey($draw->id)->lockForUpdate()->firstOrFail();

            $lockedBatch->delete();

            if ($lockedDraw->status === DrawStatus::Review->value) {
                $stillPending = DrawResultBatch::query()
                    ->where('draw_id', $lockedDraw->id)
                    ->where('status', DrawResultBatchStatus::PendingReview->value)
                    ->exists();

                if (! $stillPending) {
                    $hasPublished = DrawResultBatch::query()
                        ->where('draw_id', $lockedDraw->id)
                        ->where('status', DrawResultBatchStatus::Published->value)
                        ->exists();

                    $lockedDraw->forceFill([
                        'status' => DrawStatus::Closed->value,
                        'result_source' => $hasPublished ? $lockedDraw->result_source : null,
                    ])->save();
                }
            }

            return $lockedDraw->refresh();
        });
    }
}
