<?php

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

use App\Models\Draw;
use App\Models\TicketItem;
use App\Models\TicketOrder;
use App\Models\AdminUser;
use App\Support\ApiResponse;
use App\Models\SettlementBatch;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Lottery\ErrorCode;
use App\Support\AdminDrawResponsePolicy;
use App\Support\AdminScopePolicy;
use App\Support\ApiMessage;

/**
 * GET /api/v1/admin/draws/{draw}/finance-summary — 单期投注/派彩汇总（客服/财务视角，PRD §15.4）。
 *
 * 口径：以订单实扣汇总为「当期投注」；以注项中奖+Jackpot 为「当期派彩」；差额为近似毛损益（不含回水等细项）。
 */
final class AdminDrawFinanceSummaryController extends Controller
{
    public function __invoke(\Illuminate\Http\Request $request, Draw $draw): JsonResponse
    {
        $admin = $request->lotteryAdmin();
        abort_if(! $admin instanceof AdminUser, 401);

        if (! AdminDrawResponsePolicy::canViewDrawFinance($admin)) {
            return ApiMessage::errorResponse(
                $request,
                'admin.permission_denied',
                ErrorCode::AdminForbidden->value,
                null,
                403,
            );
        }

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

        $drawId = (int) $draw->id;

        $orders = TicketOrder::query()->where('draw_id', $drawId);
        $items = TicketItem::query()->where('draw_id', $drawId);
        AdminScopePolicy::applyViaPlayer($orders, $scope);
        AdminScopePolicy::applyViaPlayer($items, $scope);

        $totalBetMinor = (int) (clone $orders)->sum('total_actual_deduct');
        $orderCount = (int) (clone $orders)->count();
        $itemCount = (int) (clone $items)->count();

        $currencyCode = (string) ((clone $orders)->value('currency_code') ?? '');

        $totalWinMinor = (int) (clone $items)->sum('win_amount');
        $totalJackpotWinMinor = (int) (clone $items)->sum('jackpot_win_amount');
        $totalPayoutMinor = $totalWinMinor + $totalJackpotWinMinor;
        $approxHouseGrossMinor = $totalBetMinor - $totalPayoutMinor;

        $batches = SettlementBatch::query()
            ->where('draw_id', $drawId)
            ->orderByDesc('id')
            ->limit(30)
            ->get(['id', 'status', 'total_ticket_count', 'total_win_count', 'total_payout_amount', 'total_jackpot_payout_amount', 'finished_at']);

        $batchRows = $batches->map(static function (SettlementBatch $b): array {
            return [
                'id' => (int) $b->id,
                'status' => $b->status,
                'total_ticket_count' => (int) $b->total_ticket_count,
                'total_win_count' => (int) $b->total_win_count,
                'total_payout_amount' => (int) $b->total_payout_amount,
                'total_jackpot_payout_amount' => (int) $b->total_jackpot_payout_amount,
                'finished_at' => $b->finished_at?->toIso8601String(),
            ];
        })->values()->all();

        return ApiResponse::success([
            'draw_id' => $drawId,
            'draw_no' => $draw->draw_no,
            'draw_status' => $draw->status,
            'currency_code' => $currencyCode !== '' ? $currencyCode : null,
            'order_count' => $orderCount,
            'ticket_item_count' => $itemCount,
            'total_bet_minor' => $totalBetMinor,
            'total_win_payout_minor' => $totalWinMinor,
            'total_jackpot_win_minor' => $totalJackpotWinMinor,
            'total_payout_minor' => $totalPayoutMinor,
            'approx_house_gross_minor' => $approxHouseGrossMinor,
            'settlement_batches' => $batchRows,
        ]);
    }
}
