<?php

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

use App\Models\Player;
use App\Models\TicketItem;
use App\Support\ApiResponse;
use App\Support\CurrencyFormatter;
use App\Support\PaginationTrait;
use App\Support\AdminSiteScope;
use App\Support\TicketItemListFilters;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\AdminPlayerTicketItemsRequest;

/**
 * GET /api/v1/admin/players/{player}/ticket-items — 客服/财务按玩家查注单（PRD §15.4）。
 *
 * Query：`page`、`per_page`（最大 50）、`draw_no`、`status[]`、`number`、`start_date`、`end_date`。
 */
final class AdminPlayerTicketItemsIndexController extends Controller
{
    use PaginationTrait;
    use TicketItemListFilters;

    public function __invoke(AdminPlayerTicketItemsRequest $request, Player $player): JsonResponse
    {
        $admin = $request->lotteryAdmin();
        abort_if($admin === null, 401);

        if ($denied = AdminSiteScope::denyUnlessPlayerAccessible($admin, $player)) {
            return $denied;
        }

        $perPage = $this->perPage($request, 'per_page', 10, 50);
        $page = $this->page($request);
        $drawNo = $request->validated('draw_no');
        if (is_string($drawNo)) {
            $drawNo = trim($drawNo);
        }
        $statusInput = $request->validated('status', []);
        if (is_string($statusInput)) {
            $statusInput = [$statusInput];
        }
        $statusValues = is_array($statusInput) ? array_values(array_filter(array_map(
            fn ($status) => is_string($status) ? trim($status) : '',
            $statusInput,
        ))) : [];
        $number = trim((string) $request->validated('number', ''));
        $startDate = $request->validated('start_date');
        $endDate = $request->validated('end_date');

        $query = TicketItem::query()
            ->where('ticket_items.player_id', $player->id)
            ->with([
                'draw:id,draw_no,business_date',
                'order:id,order_no,currency_code,created_at',
            ])
            ->orderByDesc('ticket_items.id');

        if (is_string($drawNo) && $drawNo !== '') {
            $query->whereHas('draw', fn ($q) => $q->where('draw_no', $drawNo));
        }

        if ($statusValues !== []) {
            $query->whereIn('ticket_items.status', $statusValues);
        }

        $this->applyTicketItemNumberSearch($query, $number);
        $this->applyOrderPlacedDateRange($query, $startDate, $endDate);

        $paginator = $query->paginate(perPage: $perPage, page: $page, columns: ['*']);

        $items = collect($paginator->items())->map(function (TicketItem $row): array {
            $totalBet = (int) $row->total_bet_amount;
            $actualDeduct = (int) $row->actual_deduct_amount;
            $winAmount = (int) $row->win_amount;
            $jackpotWin = (int) $row->jackpot_win_amount;

            return [
                'ticket_no' => $row->ticket_no,
                'order_no' => $row->order?->order_no,
                'draw_no' => $row->draw?->draw_no,
                'currency_code' => $row->order?->currency_code,
                'play_code' => $row->play_code,
                'original_number' => $row->original_number,
                // 历史字段：保留兼容，实际单位为 minor。
                'total_bet_amount' => $totalBet,
                'total_bet_amount_minor' => $totalBet,
                'total_bet_amount_formatted' => CurrencyFormatter::fromMinor($totalBet),
                // 历史字段：保留兼容，实际单位为 minor。
                'actual_deduct_amount' => $actualDeduct,
                'actual_deduct_amount_minor' => $actualDeduct,
                'actual_deduct_amount_formatted' => CurrencyFormatter::fromMinor($actualDeduct),
                'status' => $row->status,
                'fail_reason_code' => $row->fail_reason_code,
                'fail_reason_text' => $row->fail_reason_text,
                // 历史字段：保留兼容，实际单位为 minor。
                'win_amount' => $winAmount,
                'win_amount_minor' => $winAmount,
                'win_amount_formatted' => CurrencyFormatter::fromMinor($winAmount),
                // 历史字段：保留兼容，实际单位为 minor。
                'jackpot_win_amount' => $jackpotWin,
                'jackpot_win_amount_minor' => $jackpotWin,
                'jackpot_win_amount_formatted' => CurrencyFormatter::fromMinor($jackpotWin),
                'placed_at' => $row->order?->created_at?->toIso8601String(),
                'updated_at' => $row->updated_at?->toIso8601String(),
            ];
        })->values()->all();

        return ApiResponse::success([
            'player_id' => (int) $player->id,
            'items' => $items,
            'total' => $paginator->total(),
            'page' => $paginator->currentPage(),
            'per_page' => $paginator->perPage(),
            'last_page' => $paginator->lastPage(),
        ]);
    }
}
