<?php

namespace App\Http\Controllers\Api\V1\Admin\Draw;

use App\Models\Draw;
use App\Lottery\ErrorCode;
use App\Support\ApiResponse;
use App\Support\ApiMessage;
use App\Lottery\DrawStatus;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
use App\Services\Draw\DrawRngRunner;
use App\Models\DrawResultBatch;

final class DrawRngRunController extends Controller
{
    public function __construct(
        private readonly DrawRngRunner $rng,
    ) {}

    public function __invoke(Draw $draw): JsonResponse
    {
        try {
            $batch = DB::transaction(function () use ($draw) {
                /** @var Draw $locked */
                $locked = Draw::query()->whereKey($draw->id)->lockForUpdate()->firstOrFail();
                if ($locked->status !== DrawStatus::Closed->value || (int) $locked->settle_version > 0) {
                    throw new \RuntimeException('draw_not_runnable');
                }
                if (! (bool) $locked->is_reopened && $locked->resultBatches()->exists()) {
                    throw new \RuntimeException('draw_not_runnable');
                }

                return $this->rng->executeLocked($locked);
            });
        } catch (\RuntimeException $e) {
            return ApiMessage::runtimeErrorResponse(request(), $e);
        }

        $draw->refresh();
        $batches = DrawResultBatch::query()
            ->where('draw_id', $draw->id)
            ->where('result_version', (int) $batch->result_version)
            ->where('source_type', $batch->source_type)
            ->orderBy('provider_code')
            ->get();

        return ApiResponse::success([
            'draw_no' => $draw->draw_no,
            'status' => $draw->status,
            'batch' => [
                'id' => (int) $batch->id,
                'provider_code' => $batch->provider_code,
                'provider_name' => $batch->provider_name,
                'result_version' => (int) $batch->result_version,
                'source_type' => $batch->source_type,
                'status' => $batch->status,
                'items_count' => $batch->items()->count(),
            ],
            'batches' => $batches->map(fn (DrawResultBatch $row): array => [
                'id' => (int) $row->id,
                'provider_code' => $row->provider_code,
                'provider_name' => $row->provider_name,
                'result_version' => (int) $row->result_version,
                'source_type' => $row->source_type,
                'status' => $row->status,
                'items_count' => $row->items()->count(),
            ])->values()->all(),
        ]);
    }
}
