<?php

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

use App\Models\Player;
use App\Lottery\ErrorCode;
use App\Support\ApiMessage;
use App\Support\ApiResponse;
use App\Support\LotteryMessage;
use App\Support\CurrencyResolver;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Exceptions\WalletOperationException;
use App\Services\Wallet\LotteryTransferService;
use App\Http\Requests\Wallet\WalletTransferRequest;

/**
 * 转入：主站扣款 → 彩票钱包加款。
 *
 * `POST /api/v1/wallet/transfer-in` ，body JSON：`amount`（最小货币单位整数）, `idempotent_key`, `currency`（可选）
 */
final class WalletTransferInController extends Controller
{
    public function __construct(
        private readonly LotteryTransferService $transferService,
    ) {}

    public function __invoke(WalletTransferRequest $request): JsonResponse
    {
        $player = $request->lotteryPlayer();
        abort_if($player === null, 500, 'lottery_player missing');

        $currency = $this->resolveCurrencyCode($request, $player);
        if ($currency instanceof JsonResponse) {
            return $currency;
        }

        try {
            $data = $this->transferService->transferIn(
                $player,
                $currency,
                (int) $request->validated('amount'),
                (string) $request->validated('idempotent_key'),
            );
        } catch (WalletOperationException $e) {
            return ApiResponse::error(
                LotteryMessage::wallet($request, $e->lotteryCode),
                $e->lotteryCode,
                null,
                $e->httpStatus,
            );
        }

        return ApiResponse::success($data);
    }

    private function resolveCurrencyCode(WalletTransferRequest $request, Player $player): string|JsonResponse
    {
        $code = CurrencyResolver::resolve($request, $player, 'currency');

        if (! CurrencyResolver::isEnabled($code)) {
            return ApiResponse::error(
                ApiMessage::get($request, 'wallet.invalid_currency'),
                ErrorCode::WalletInvalidCurrency->value,
                null,
                400,
            );
        }

        return $code;
    }
}
