<?php

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

use App\Http\Controllers\Controller;
use App\Support\ApiResponse;
use App\Support\CurrencyFormatter;
use App\Support\PlayerFundingMode;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

/** GET /api/v1/wallet/settlement-bills：信用盘玩家自己的账期账单摘要。 */
final class WalletSettlementBillsController extends Controller
{
    public function __invoke(Request $request): JsonResponse
    {
        $player = $request->lotteryPlayer();
        abort_if($player === null, 500, 'lottery_player missing');

        if (! PlayerFundingMode::usesCredit($player)) {
            return ApiResponse::success([
                'items' => [],
                'summary' => [
                    'pending_receivable' => 0,
                    'pending_payable' => 0,
                    'net_pending' => 0,
                    'pending_count' => 0,
                ],
                'funding_mode' => (string) ($player->funding_mode ?? PlayerFundingMode::WALLET),
            ]);
        }

        $rows = DB::table('settlement_bills as sb')
            ->join('settlement_periods as sp', 'sp.id', '=', 'sb.settlement_period_id')
            ->where('sb.bill_type', 'player')
            ->where('sb.owner_type', 'player')
            ->where('sb.owner_id', (int) $player->id)
            ->whereIn('sb.status', ['pending_confirm', 'confirmed', 'partial_paid', 'overdue'])
            ->orderByDesc('sp.period_end')
            ->orderByDesc('sb.id')
            ->limit(5)
            ->get([
                'sb.id',
                'sb.settlement_period_id',
                'sb.gross_win_loss',
                'sb.rebate_amount',
                'sb.net_amount',
                'sb.paid_amount',
                'sb.unpaid_amount',
                'sb.status',
                'sp.period_start',
                'sp.period_end',
            ]);

        $pendingReceivable = 0;
        $pendingPayable = 0;
        $items = $rows->map(function (object $row) use (&$pendingReceivable, &$pendingPayable): array {
            $netAmount = (int) $row->net_amount;
            $unpaidAmount = (int) $row->unpaid_amount;
            $direction = $netAmount > 0 ? 'payable' : 'receivable';

            if ($direction === 'payable') {
                $pendingPayable += $unpaidAmount;
            } else {
                $pendingReceivable += $unpaidAmount;
            }

            return [
                'id' => (int) $row->id,
                'settlement_period_id' => (int) $row->settlement_period_id,
                'period_start' => $this->isoTimestamp($row->period_start),
                'period_end' => $this->isoTimestamp($row->period_end),
                'gross_win_loss' => (int) $row->gross_win_loss,
                'rebate_amount' => (int) $row->rebate_amount,
                'net_amount' => $netAmount,
                'paid_amount' => (int) $row->paid_amount,
                'unpaid_amount' => $unpaidAmount,
                'direction' => $direction,
                'status' => (string) $row->status,
            ];
        })->all();

        return ApiResponse::success([
            'items' => $items,
            'summary' => [
                'pending_receivable' => $pendingReceivable,
                'pending_receivable_formatted' => CurrencyFormatter::fromMinor($pendingReceivable),
                'pending_payable' => $pendingPayable,
                'pending_payable_formatted' => CurrencyFormatter::fromMinor($pendingPayable),
                'net_pending' => $pendingReceivable - $pendingPayable,
                'net_pending_formatted' => CurrencyFormatter::fromMinor(abs($pendingReceivable - $pendingPayable)),
                'pending_count' => count($items),
            ],
            'funding_mode' => PlayerFundingMode::CREDIT,
        ]);
    }

    private function isoTimestamp(mixed $value): ?string
    {
        if ($value === null || $value === '') {
            return null;
        }

        return \Carbon\Carbon::parse((string) $value)->toIso8601String();
    }
}
