<?php

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

use App\Http\Controllers\Controller;
use App\Lottery\ErrorCode;
use App\Models\TicketItem;
use App\Support\AdminScopePolicy;
use App\Support\ApiResponse;
use App\Support\CurrencyFormatter;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

/**
 * GET /api/v1/admin/tickets/{ticket_no} — 注单详情（含展开组合）。
 */
final class AdminTicketItemShowController extends Controller
{
    public function __invoke(Request $request, string $ticket_no): JsonResponse
    {
        $admin = $request->lotteryAdmin();
        abort_if($admin === null, 401);

        $ticketNo = trim($ticket_no);
        $scope = AdminScopePolicy::resolveContext($request, $admin);

        $query = TicketItem::query()
            ->where('ticket_no', $ticketNo)
            ->with([
                'combinations',
                'draw:id,draw_no,business_date',
                'order:id,order_no,currency_code,created_at,status',
                'player:id,site_code,site_player_id,username,nickname,agent_node_id,funding_mode',
                'player.agentNode:id,code,name',
            ]);

        AdminScopePolicy::applyViaPlayerRelationWithContext($query, $scope, 'player');

        $item = $query->first();
        if ($item === null) {
            return ApiResponse::error(
                trans('api.not_found', [], $request->lotteryLocale()),
                ErrorCode::NotFound->value,
                null,
                404,
            );
        }

        $totalBet = (int) $item->total_bet_amount;
        $actualDeduct = (int) $item->actual_deduct_amount;

        return ApiResponse::success([
            'id' => (int) $item->id,
            'ticket_no' => $item->ticket_no,
            'order_no' => $item->order?->order_no,
            'order_status' => $item->order?->status,
            'draw_id' => (int) $item->draw_id,
            'draw_no' => $item->draw?->draw_no,
            'currency_code' => $item->order?->currency_code,
            'player_id' => $item->player_id,
            'site_code' => $item->player?->site_code,
            'site_player_id' => $item->player?->site_player_id,
            'username' => $item->player?->username,
            'nickname' => $item->player?->nickname,
            'funding_mode' => $item->player?->funding_mode,
            'agent_node_id' => $item->player?->agent_node_id,
            'agent_code' => $item->player?->agentNode?->code,
            'agent_name' => $item->player?->agentNode?->name,
            'play_code' => $item->play_code,
            'dimension' => $item->dimension,
            'digit_slot' => $item->digit_slot,
            'original_number' => $item->original_number,
            'normalized_number' => $item->normalized_number,
            'combination_count' => (int) $item->combination_count,
            'unit_bet_amount' => (int) $item->unit_bet_amount,
            'total_bet_amount_minor' => $totalBet,
            'total_bet_amount_formatted' => CurrencyFormatter::fromMinor($totalBet),
            'actual_deduct_amount_minor' => $actualDeduct,
            'actual_deduct_amount_formatted' => CurrencyFormatter::fromMinor($actualDeduct),
            'risk_locked_amount' => (int) $item->risk_locked_amount,
            'status' => $item->status,
            'fail_reason_code' => $item->fail_reason_code,
            'fail_reason_text' => $item->fail_reason_text,
            'win_amount_minor' => (int) $item->win_amount,
            'win_amount_formatted' => CurrencyFormatter::fromMinor((int) $item->win_amount),
            'placed_at' => $item->order?->created_at?->toIso8601String(),
            'updated_at' => $item->updated_at?->toIso8601String(),
            'combinations' => $item->combinations
                ->sortBy('combination_no')
                ->values()
                ->map(fn ($combo): array => [
                    'combination_no' => (int) $combo->combination_no,
                    'number_4d' => (string) $combo->number_4d,
                    'bet_amount' => (int) $combo->bet_amount,
                    'estimated_payout' => (int) $combo->estimated_payout,
                ])
                ->all(),
        ]);
    }
}
