<?php

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

use App\Lottery\ErrorCode;
use App\Support\ApiResponse;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;

/**
 * E2E 辅助：重置/查询玩家状态。
 *
 * - reset: 失败计数 / 锁定 / 余额 / 状态 → 全部归位
 * - set-balance: 强制把 player_wallets.balance 写成指定值（不改 frozen，避开版本锁）
 * - unlock: 仅清失败计数 + 锁定（不动余额）
 * - inspect: 返回玩家当前完整状态快照（用于断言前的状态探查）
 *
 * 严格仅在 LOTTERY_E2E=true 时由 E2EServiceProvider 注册。
 */
final class E2EPlayerStateController extends Controller
{
    public function reset(Request $request): JsonResponse
    {
        $username = (string) env('E2E_PLAYER_USERNAME', 'demo_player');
        $siteCode = (string) env('E2E_PLAYER_SITE_CODE', 'demo');
        $balance = (int) env('DEV_SEED_WALLET_BALANCE_MINOR', 1_250_000);
        $currency = strtoupper((string) env('LOTTERY_DEFAULT_CURRENCY', config('lottery.default_currency', 'NPR')));

        $playerId = DB::table('players')
            ->where('site_code', $siteCode)
            ->where('username', $username)
            ->value('id');

        if (! $playerId) {
            return ApiResponse::error('e2e player not found', ErrorCode::NotFound->value, null, 404);
        }

        DB::transaction(function () use ($playerId, $balance, $currency) {
            DB::table('players')
                ->where('id', $playerId)
                ->update([
                    'login_failed_count' => 0,
                    'login_locked_until' => null,
                    'status' => 0,
                ]);
            DB::table('player_wallets')
                ->where('player_id', $playerId)
                ->where('wallet_type', 'lottery')
                ->where('currency_code', $currency)
                ->update([
                    'balance' => $balance,
                    'frozen_balance' => 0,
                    'version' => DB::raw('version + 1'),
                ]);
        });

        return ApiResponse::success([
            'player_id' => (int) $playerId,
            'username' => $username,
            'balance' => $balance,
            'currency' => $currency,
        ]);
    }

    public function setBalance(Request $request): JsonResponse
    {
        $username = (string) env('E2E_PLAYER_USERNAME', 'demo_player');
        $siteCode = (string) env('E2E_PLAYER_SITE_CODE', 'demo');
        $currency = strtoupper((string) $request->input('currency', config('lottery.default_currency', 'NPR')));
        $balance = (int) $request->input('balance', -1);

        if ($balance < 0) {
            return ApiResponse::error('balance must be >= 0', ErrorCode::ValidationFailed->value, null, 422);
        }

        $playerId = DB::table('players')
            ->where('site_code', $siteCode)
            ->where('username', $username)
            ->value('id');

        if (! $playerId) {
            return ApiResponse::error('e2e player not found', ErrorCode::NotFound->value, null, 404);
        }

        DB::table('player_wallets')
            ->where('player_id', $playerId)
            ->where('wallet_type', 'lottery')
            ->where('currency_code', $currency)
            ->update([
                'balance' => $balance,
                'frozen_balance' => 0,
                'version' => DB::raw('version + 1'),
            ]);

        return ApiResponse::success([
            'player_id' => (int) $playerId,
            'balance' => $balance,
            'currency' => $currency,
        ]);
    }

    public function unlock(Request $request): JsonResponse
    {
        $username = (string) env('E2E_PLAYER_USERNAME', 'demo_player');
        $siteCode = (string) env('E2E_PLAYER_SITE_CODE', 'demo');

        $affected = DB::table('players')
            ->where('site_code', $siteCode)
            ->where('username', $username)
            ->update([
                'login_failed_count' => 0,
                'login_locked_until' => null,
                'status' => 0,
            ]);

        return ApiResponse::success([
            'username' => $username,
            'affected_rows' => $affected,
        ]);
    }

    public function inspect(Request $request): JsonResponse
    {
        $username = (string) env('E2E_PLAYER_USERNAME', 'demo_player');
        $siteCode = (string) env('E2E_PLAYER_SITE_CODE', 'demo');

        $player = DB::table('players')
            ->where('site_code', $siteCode)
            ->where('username', $username)
            ->first();

        if (! $player) {
            return ApiResponse::error('e2e player not found', ErrorCode::NotFound->value, null, 404);
        }

        $wallets = DB::table('player_wallets')
            ->where('player_id', $player->id)
            ->get(['wallet_type', 'currency_code', 'balance', 'frozen_balance', 'status', 'version']);

        return ApiResponse::success([
            'player' => [
                'id' => (int) $player->id,
                'username' => $player->username,
                'site_code' => $player->site_code,
                'auth_source' => $player->auth_source,
                'funding_mode' => $player->funding_mode,
                'status' => (int) $player->status,
                'login_failed_count' => (int) $player->login_failed_count,
                'login_locked_until' => $player->login_locked_until,
                'default_currency' => $player->default_currency,
            ],
            'wallets' => $wallets->map(fn ($w) => [
                'wallet_type' => $w->wallet_type,
                'currency_code' => $w->currency_code,
                'balance' => (int) $w->balance,
                'frozen_balance' => (int) $w->frozen_balance,
                'status' => (int) $w->status,
                'version' => (int) $w->version,
            ])->values()->all(),
        ]);
    }
}
