<?php

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

use App\Models\Draw;
use App\Models\RiskPool;
use App\Models\TicketOrder;
use Illuminate\Http\Request;
use App\Support\AdminApiList;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;

/**
 * GET /api/v1/admin/draws/{draw}/risk-pools — 按期号分页查询赔付池事实（售罄筛选、排序）。
 *
 * 对齐产品文档：后台查看售罄与风险占用、热门号码监控（按占用排序）。
 */
final class AdminRiskPoolIndexController extends Controller
{
    public function __invoke(Request $request, Draw $draw): JsonResponse
    {
        $p = AdminApiList::readPaging($request);
        $soldOutOnly = $request->boolean('sold_out_only');
        $highRiskOnly = $request->boolean('high_risk_only');
        $activeOnly = $request->boolean('active_only');
        $number = trim((string) $request->query('normalized_number', ''));
        $sort = trim((string) $request->query('sort', 'usage_desc'));

        $q = RiskPool::query()->where('draw_id', $draw->id);

        if ($soldOutOnly) {
            $q->where('sold_out_status', 1);
        }
        if ($highRiskOnly) {
            $q->whereRaw('(locked_amount * 1.0 / NULLIF(total_cap_amount, 0)) >= 0.8');
        }
        if ($activeOnly) {
            $q->where(function ($inner): void {
                $inner->where('locked_amount', '>', 0)
                    ->orWhere('sold_out_status', 1)
                    ->orWhereRaw('(locked_amount * 1.0 / NULLIF(total_cap_amount, 0)) >= 0.8');
            });
        }
        if ($number !== '') {
            $q->where('normalized_number', 'like', '%'.$number.'%');
        }

        match ($sort) {
            'locked_desc' => $q->orderByDesc('locked_amount')->orderBy('normalized_number'),
            'remaining_asc' => $q->orderBy('remaining_amount')->orderBy('normalized_number'),
            'number_asc' => $q->orderBy('normalized_number'),
            default => $q->orderByRaw('(locked_amount * 1.0 / NULLIF(total_cap_amount, 0)) DESC')
                ->orderByDesc('locked_amount')
                ->orderBy('normalized_number'),
        };

        /** @var LengthAwarePaginator $paginator */
        $paginator = $q->paginate($p['perPage'], ['*'], 'page', $p['page']);

        $currencyCode = (string) (TicketOrder::query()
            ->where('draw_id', $draw->id)
            ->value('currency_code') ?? '');

        return AdminApiList::jsonWith($paginator, fn (RiskPool $row) => $this->row($row), [
            'draw_id' => (int) $draw->id,
            'draw_no' => $draw->draw_no,
            'currency_code' => $currencyCode !== '' ? $currencyCode : null,
        ]);
    }

    /** @return array<string, mixed> */
    private function row(RiskPool $pool): array
    {
        $cap = (int) $pool->total_cap_amount;
        $locked = (int) $pool->locked_amount;

        return [
            'normalized_number' => $pool->normalized_number,
            'total_cap_amount' => $cap,
            'locked_amount' => $locked,
            'remaining_amount' => (int) $pool->remaining_amount,
            'sold_out_status' => (int) $pool->sold_out_status,
            'is_sold_out' => (int) $pool->sold_out_status === 1,
            'usage_ratio' => $cap > 0 ? round($locked / $cap, 6) : null,
            'version' => (int) $pool->version,
        ];
    }
}
