<?php

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

use App\Models\Draw;
use App\Models\TicketOrder;
use Illuminate\Http\Request;
use App\Support\AdminApiList;
use App\Models\RiskPoolLockLog;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use App\Services\Admin\AdminRiskPoolLockLogQueryService;

/**
 * GET /api/v1/admin/draws/{draw}/risk-pool-lock-logs — 风险池占用/释放流水（审计与监控）。
 *
 * Query：`group_by=ticket`（默认，按注单聚合）| `entry`（按号码明细）；
 * `ticket_item_id` 可筛单注；`action_type`、`normalized_number` 同前。
 */
final class AdminRiskPoolLockLogIndexController extends Controller
{
    public function __construct(
        private readonly AdminRiskPoolLockLogQueryService $queryService,
    ) {}

    public function __invoke(Request $request, Draw $draw): JsonResponse
    {
        $p = AdminApiList::readPaging($request);
        $groupBy = trim((string) $request->query('group_by', 'ticket'));
        if (! in_array($groupBy, ['ticket', 'entry'], true)) {
            $groupBy = 'ticket';
        }

        /** @var LengthAwarePaginator $paginator */
        $paginator = $groupBy === 'entry'
            ? $this->queryService->paginateEntries($draw, $request, $p['page'], $p['perPage'])
            : $this->queryService->paginateByTicket($draw, $request, $p['page'], $p['perPage']);

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

        $rowMapper = $groupBy === 'entry'
            ? fn (RiskPoolLockLog $log): array => $this->entryRow($log)
            : fn (object $row): array => $this->ticketRow($row);

        return AdminApiList::jsonWith($paginator, $rowMapper, [
            'draw_id' => (int) $draw->id,
            'draw_no' => $draw->draw_no,
            'currency_code' => $currencyCode !== '' ? $currencyCode : null,
            'group_by' => $groupBy,
        ]);
    }

    /** @return array<string, mixed> */
    private function entryRow(RiskPoolLockLog $log): array
    {
        return [
            'id' => (int) $log->id,
            'normalized_number' => $log->normalized_number,
            'action_type' => $log->action_type,
            'amount' => (int) $log->amount,
            'source_reason' => $log->source_reason,
            'ticket_item_id' => $log->ticket_item_id,
            'ticket_no' => $log->ticketItem?->ticket_no,
            'play_code' => $log->ticketItem?->play_code,
            'player_id' => $log->ticketItem?->player_id,
            'created_at' => $log->created_at?->toIso8601String(),
        ];
    }

    /** @return array<string, mixed> */
    private function ticketRow(object $row): array
    {
        $lastAt = $row->last_at ?? null;

        return [
            'ticket_item_id' => (int) $row->ticket_item_id,
            'ticket_no' => (string) $row->ticket_no,
            'play_code' => (string) $row->play_code,
            'original_number' => (string) $row->original_number,
            'combination_count' => (int) $row->combination_count,
            'player_id' => (int) $row->player_id,
            'number_count' => (int) $row->number_count,
            'lock_entry_count' => (int) $row->lock_entry_count,
            'release_entry_count' => (int) $row->release_entry_count,
            'total_lock_amount' => (int) $row->total_lock_amount,
            'total_release_amount' => (int) $row->total_release_amount,
            'last_at' => is_string($lastAt) ? $lastAt : null,
        ];
    }
}
