<?php

namespace App\Http\Controllers\Api\V1\Ticket;

use App\Models\Player;
use App\Models\TicketItem;
use App\Support\ApiResponse;
use App\Support\TicketItemListFilters;
use Illuminate\Http\Request;
use App\Support\PaginationTrait;
use Illuminate\Http\JsonResponse;
use App\Support\CurrencyFormatter;
use App\Http\Controllers\Controller;

/**
 * `GET /api/v1/ticket/items` — 我的注单（注项列表，支持 `draw_no` 筛选）。
 */
final class TicketItemsIndexController extends Controller
{
    use PaginationTrait;
    use TicketItemListFilters;

    public function __invoke(Request $request): JsonResponse
    {
        /** @var Player $player */
        $player = $request->attributes->get('lottery_player');

        $perPage = $this->perPage($request, 'per_page', 10, 50);
        $page = $this->page($request);
        $drawNo = $request->query('draw_no');
        $statusInput = $request->query('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->query('number', ''));
        $orderNo = trim((string) $request->query('order_no', ''));
        $startDate = $this->normalizeDate((string) $request->query('start_date', ''));
        $endDate = $this->normalizeDate((string) $request->query('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,status,created_at',
            ])
            ->orderByDesc('ticket_items.id');

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

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

        if ($orderNo !== '') {
            $query->whereHas('order', fn ($q) => $q->where('order_no', $orderNo));
        }

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

        $paginator = $query->paginate(perPage: $perPage, page: $page);

        $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,
                'order_status' => $row->order?->status,
                'draw_no' => $row->draw?->draw_no,
                'currency_code' => $row->order?->currency_code,
                'play_code' => $row->play_code,
                'original_number' => $row->original_number,
                'total_bet_amount' => $totalBet,
                'total_bet_amount_formatted' => CurrencyFormatter::fromMinor($totalBet),
                'actual_deduct_amount' => $actualDeduct,
                'actual_deduct_amount_formatted' => CurrencyFormatter::fromMinor($actualDeduct),
                'status' => $row->status,
                'win_amount' => $winAmount,
                'win_amount_formatted' => CurrencyFormatter::fromMinor($winAmount),
                'jackpot_win_amount' => $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([
            'items' => $items,
            'total' => $paginator->total(),
            'page' => $paginator->currentPage(),
            'per_page' => $paginator->perPage(),
            'last_page' => $paginator->lastPage(),
        ]);
    }

    private function normalizeDate(string $value): ?string
    {
        $value = trim($value);
        if ($value === '' || ! preg_match('/^\d{4}-\d{2}-\d{2}$/', $value)) {
            return null;
        }

        return $value;
    }
}
