<?php
declare(strict_types=1);

namespace app\api\controller\v1;

use app\api\logic\UserLogic;
use app\api\util\ReturnCode;
use app\dice\model\player\DicePlayer;
use plugin\saiadmin\app\model\system\SystemUser;
use app\dice\model\play_record\DicePlayRecord;
use app\dice\model\player_wallet_record\DicePlayerWalletRecord;
use app\dice\model\player_ticket_record\DicePlayerTicketRecord;
use support\think\Db;
use app\api\controller\BaseController;
use support\Request;
use support\Response;

/**
 * 平台 v1 游戏接口
 * 请求头：auth-token
 */
class GameController extends BaseController
{
    /**
     * 获取游戏地址
     * 根据 username 创建登录 token（JWT），拼接游戏地址返回
     */
    public function getGameUrl(Request $request): Response
    {
        $username = trim((string) ($request->post('username', '')));
        $password = trim((string) ($request->post('password', '123456')));
        $time = trim((string) ($request->post('time', '')));

        if ($username === '') {
            return $this->fail('username 不能为空', ReturnCode::PARAMS_ERROR);
        }
        if ($password === '') {
            $password = '123456';
        }
        if ($time === '') {
            $time = (string) time();
        }

        $adminId = null;
        $agentId = trim((string) ($request->agent_id ?? ''));
        if ($agentId !== '') {
            $systemUser = SystemUser::where('agent_id', $agentId)->find();
            if ($systemUser) {
                $adminId = (int) $systemUser->id;
            }
        }

        $lang = trim((string) ($request->post('lang', 'zh')));
        $lang = in_array($lang, ['en', 'zh'], true) ? $lang : 'zh';

        try {
            $logic = new UserLogic();
            $result = $logic->loginByUsername($username, $password, $lang === 'en' ? 'en' : 'chs', 0.0, $time, $adminId);
        } catch (\plugin\saiadmin\exception\ApiException $e) {
            return $this->fail($e->getMessage(), ReturnCode::PARAMS_ERROR);
        }

        $gameUrlBase = rtrim(config('api.game_url', 'dice-game.yuliao666.top'), '/');
        $tokenInUrl = str_replace('%3D', '=', urlencode($result['token']));
        $url = $gameUrlBase . '/?token=' . $tokenInUrl . '&lang=' . $lang;

        return $this->success([
            'url' => $url,
        ]);
    }

    /**
     * 获取用户信息
     * POST 参数：username
     * 返回 DicePlayer 中非敏感信息
     */
    public function getPlayerInfo(Request $request): Response
    {
        $username = trim((string) ($request->post('username', '')));

        if ($username === '') {
            return $this->fail('username 不能为空', ReturnCode::PARAMS_ERROR);
        }

        $player = DicePlayer::where('username', $username)->find();
        if (!$player) {
            return $this->fail('用户不存在', ReturnCode::NOT_FOUND);
        }

        $hidden = ['password', 'lottery_config_id', 't1_weight', 't2_weight', 't3_weight', 't4_weight', 't5_weight', 'delete_time'];
        $info = $player->hidden($hidden)->toArray();

        return $this->success($info);
    }

    /**
     * 获取游戏记录
     * POST 参数：username（非必填，没填则不按用户筛选）, start_create_time, end_create_time（非必填，没填则不筛选时间）
     * 返回 DicePlayRecord 中非敏感信息
     */
    public function getPlayerGameRecord(Request $request): Response
    {
        $username = trim((string) ($request->post('username', '')));
        $startCreateTime = trim((string) ($request->post('start_create_time', '')));
        $endCreateTime = trim((string) ($request->post('end_create_time', '')));
        $page = (int) $request->post('page', 1);
        $limit = (int) $request->post('limit', 20);

        if ($page < 1) {
            $page = 1;
        }
        if ($limit < 1 || $limit > 100) {
            $limit = 20;
        }

        $query = DicePlayRecord::order('id', 'desc');

        if ($username !== '') {
            $player = DicePlayer::where('username', $username)->find();
            if (!$player) {
                return $this->success([]);
            }
            $query->where('player_id', (int) $player->id);
        }

        if ($startCreateTime !== '') {
            $query->where('create_time', '>=', $startCreateTime);
        }
        if ($endCreateTime !== '') {
            $query->where('create_time', '<=', $endCreateTime);
        }

        $list = $query->page($page, $limit)->select()->toArray();
        $playerIds = array_unique(array_column($list, 'player_id'));
        if (!empty($playerIds)) {
            $players = DicePlayer::whereIn('id', $playerIds)->field('id,username,phone')->select()->toArray();
            $playerMap = [];
            foreach ($players as $p) {
                $playerMap[(int) ($p['id'] ?? 0)] = $p;
            }
            foreach ($list as &$item) {
                $item['dice_player'] = $playerMap[(int) ($item['player_id'] ?? 0)] ?? null;
            }
        }

        return $this->success($list);
    }

    /**
     * 获取钱包流水
     * POST 参数：username（非必填，没填则不按用户筛选）, start_create_time, end_create_time（非必填，没填则不筛选时间）
     * 返回 DicePlayerWalletRecord 中非敏感信息
     */
    public function getPlayerWalletRecord(Request $request): Response
    {
        $username = trim((string) ($request->post('username', '')));
        $startCreateTime = trim((string) ($request->post('start_create_time', '')));
        $endCreateTime = trim((string) ($request->post('end_create_time', '')));
        $page = (int) $request->post('page', 1);
        $limit = (int) $request->post('limit', 20);

        if ($page < 1) {
            $page = 1;
        }
        if ($limit < 1 || $limit > 100) {
            $limit = 20;
        }

        $query = DicePlayerWalletRecord::order('id', 'desc');

        if ($username !== '') {
            $player = DicePlayer::where('username', $username)->find();
            if (!$player) {
                return $this->success([]);
            }
            $query->where('player_id', (int) $player->id);
        }

        if ($startCreateTime !== '') {
            $query->where('create_time', '>=', $startCreateTime);
        }
        if ($endCreateTime !== '') {
            $query->where('create_time', '<=', $endCreateTime);
        }

        $list = $query->with(['dicePlayer' => function ($q) {
            $q->field('id,username,phone');
        }])->page($page, $limit)->select()->toArray();

        return $this->success($list);
    }

    /**
     * 获取用户中奖券获取记录
     * POST 参数：username（非必填，没填则不按用户筛选）, start_create_time, end_create_time（非必填，没填则不筛选时间）
     * 返回 DicePlayerTicketRecord 中非敏感信息
     */
    public function getPlayerTicketRecord(Request $request): Response
    {
        $username = trim((string) ($request->post('username', '')));
        $startCreateTime = trim((string) ($request->post('start_create_time', '')));
        $endCreateTime = trim((string) ($request->post('end_create_time', '')));
        $page = (int) $request->post('page', 1);
        $limit = (int) $request->post('limit', 20);

        if ($page < 1) {
            $page = 1;
        }
        if ($limit < 1 || $limit > 100) {
            $limit = 20;
        }

        $query = DicePlayerTicketRecord::order('id', 'desc');

        if ($username !== '') {
            $player = DicePlayer::where('username', $username)->find();
            if (!$player) {
                return $this->success([]);
            }
            $query->where('player_id', (int) $player->id);
        }

        if ($startCreateTime !== '') {
            $query->where('create_time', '>=', $startCreateTime);
        }
        if ($endCreateTime !== '') {
            $query->where('create_time', '<=', $endCreateTime);
        }

        $list = $query->with(['dicePlayer' => function ($q) {
            $q->field('id,username,phone');
        }])->page($page, $limit)->select()->toArray();

        return $this->success($list);
    }

    /**
     * 钱包转入转出
     * POST 参数：username（必填）, coin（转入>0 或 转出<0）
     * 创建 DicePlayerWalletRecord，type: 0=充值(coin>0), 1=提现(coin<0)
     * 返回创建的记录
     */
    public function setPlayerWallet(Request $request): Response
    {
        $username = trim((string) ($request->post('username', '')));
        $coin = $request->post('coin');

        if ($username === '') {
            return $this->fail('username 不能为空', ReturnCode::PARAMS_ERROR);
        }
        if ($coin === null || $coin === '') {
            return $this->fail('coin 不能为空', ReturnCode::PARAMS_ERROR);
        }

        $coinVal = (float) $coin;
        if ($coinVal === 0.0) {
            return $this->fail('coin 不能为 0', ReturnCode::PARAMS_ERROR);
        }

        $player = DicePlayer::where('username', $username)->find();
        if (!$player) {
            return $this->fail('用户不存在', ReturnCode::NOT_FOUND);
        }

        $walletBefore = (float) ($player->coin ?? 0);
        $walletAfter = $walletBefore + $coinVal;

        if ($coinVal < 0 && $walletBefore < -$coinVal) {
            return $this->fail('余额不足，无法转出', ReturnCode::BUSINESS_ERROR);
        }

        $type = $coinVal > 0 ? 0 : 1;
        $remark = $coinVal > 0 ? '充值' : '提现';

        try {
            Db::startTrans();
            $player->coin = $walletAfter;
            $player->save();

            $adminId = ($player->admin_id ?? null) ? (int) $player->admin_id : null;
            $record = DicePlayerWalletRecord::create([
                'player_id' => (int) $player->id,
                'admin_id' => $adminId,
                'coin' => $coinVal,
                'type' => $type,
                'wallet_before' => $walletBefore,
                'wallet_after' => $walletAfter,
                'total_ticket_count' => 0,
                'paid_ticket_count' => 0,
                'free_ticket_count' => 0,
                'remark' => $remark,
                'user_id' => 0,
            ]);
            Db::commit();
        } catch (\Throwable $e) {
            Db::rollback();
            return $this->fail('操作失败：' . $e->getMessage(), ReturnCode::SERVER_ERROR);
        }

        $recordArr = $record->toArray();
        $recordArr['dice_player'] = ['id' => (int) $player->id, 'username' => $player->username ?? '', 'phone' => $player->phone ?? ''];
        return $this->success($recordArr);
    }
}
