<?php
declare(strict_types=1);

namespace app\api\controller;

use support\Request;
use support\Response;
use app\api\cache\UserCache;
use app\api\logic\UserLogic;
use app\api\util\ReturnCode;
use app\dice\model\play_record\DicePlayRecord;
use app\dice\model\player_wallet_record\DicePlayerWalletRecord;
use app\api\controller\BaseController;

/**
 * API 用户登录等
 * 登录接口 /api/user/Login 无需 token；其余接口需在请求头携带 token（base64(username.-.time)），由 TokenMiddleware 鉴权并注入 request->player_id / request->player
 */
class UserController extends BaseController
{
    /**
     * 登录（form-data 参数）
     * POST /api/user/Login
     * body: username, password, lang(可选), coin(可选), time(可选)
     * 根据 username 查找或创建 DicePlayer，按 coin 增减平台币，会话写 Redis，返回带 token 的连接地址
     */
    public function Login(Request $request): Response
    {
        $usernameRaw = $request->post('username', '');
        $passwordRaw = $request->post('password', '');
        $langRaw = $request->post('lang', 'zh');

        $username = is_string($usernameRaw) ? trim($usernameRaw) : '';
        $password = is_string($passwordRaw) ? trim($passwordRaw) : '';
        $lang = is_string($langRaw) ? trim($langRaw) : 'zh';
        $coin = $request->post('coin');
        $coin = $coin !== null && $coin !== '' ? (float) $coin : 0.0;
        $time = $request->post('time');
        $time = $time !== null && $time !== '' ? (string) $time : (string) time();
        if ($username === '' || $password === '') {
            return $this->fail('USERNAME_PASSWORD_REQUIRED', ReturnCode::PARAMS_ERROR);
        }

        try {
            $logic = new UserLogic();
            $result = $logic->loginByUsername($username, $password, $lang, $coin, $time);
            return $this->success([
                'url' => $result['url'],
                'token' => $result['token'],
                'lang' => $result['lang'],
                'user_id' => $result['user_id'],
                'user' => $result['user'],
            ]);
        } catch (\plugin\saiadmin\exception\ApiException $e) {
            return $this->fail($e->getMessage(), ReturnCode::PARAMS_ERROR);
        }
    }

    /**
     * 退出登录
     * POST /api/user/logout
     * header: token（JWT），清除该 username 的 Redis 会话
     */
    public function logout(Request $request): Response
    {
        $token = $request->header('token');
        if ($token === null || $token === '') {
            $auth = $request->header('authorization');
            if ($auth && stripos($auth, 'Bearer ') === 0) {
                $token = trim(substr($auth, 7));
            }
        }
        $token = $token !== null ? trim((string) $token) : '';
        if ($token === '') {
            return $this->fail('Please provide token', ReturnCode::UNAUTHORIZED);
        }
        $username = UserLogic::getUsernameFromJwtPayload($token);
        if ($username === null || $username === '') {
            return $this->fail('Invalid or expired token', ReturnCode::TOKEN_INVALID);
        }
        UserCache::deleteSessionByUsername($username);
        UserCache::deletePlayerByUsername($username);
        return $this->success('Logged out successfully');
    }

    /**
     * 获取当前用户信息
     * GET /api/user/info
     * header: token（由 TokenMiddleware 校验并注入 request->player_id）
     */
    public function info(Request $request): Response
    {
        $userId = (int) ($request->player_id ?? 0);
        $user = UserLogic::getCachedUser($userId);
        if (empty($user)) {
            return $this->fail('User not found', ReturnCode::NOT_FOUND);
        }
        $fields = ['id', 'username', 'phone', 'uid', 'name', 'coin', 'total_ticket_count', 'free_ticket'];
        $info = [];
        foreach ($fields as $field) {
            if (array_key_exists($field, $user)) {
                $info[$field] = $user[$field];
            }
        }
        return $this->success($info);
    }

    /**
     * 获取钱包余额（优先读缓存）
     * GET /api/user/balance
     * header: token（由 TokenMiddleware 注入 request->player_id）
     */
    public function balance(Request $request): Response
    {
        $userId = (int) ($request->player_id ?? 0);
        $user = UserLogic::getCachedUser($userId);
        if (empty($user)) {
            return $this->fail('User not found', ReturnCode::NOT_FOUND);
        }
        $coin = $user['coin'] ?? 0;
        if (is_string($coin) && is_numeric($coin)) {
            $coin = str_contains($coin, '.') ? (float) $coin : (int) $coin;
        }
        return $this->success([
            'coin' => $coin,
            'phone' => $user['phone'] ?? '',
            'username' => $user['username'] ?? '',
        ]);
    }

    /**
     * 玩家钱包流水
     * GET /api/user/walletRecord
     * header: token（由 TokenMiddleware 注入 request->player_id）
     * 参数: page 页码（默认1）, limit 每页条数（默认10）, create_time_min/create_time_max 创建时间范围（可选）
     */
    public function walletRecord(Request $request): Response
    {
        $userId = (int) ($request->player_id ?? 0);
        $page = (int) $request->post('page', 1);
        $limit = (int) $request->post('limit', 10);
        if ($page < 1) {
            $page = 1;
        }
        if ($limit < 1) {
            $limit = 10;
        }

        $query = DicePlayerWalletRecord::where('player_id', $userId)->order('id', 'desc');

        $createTimeMin = $request->post('create_time_min', '');
        $createTimeMax = $request->post('create_time_max', '');
        if ($createTimeMin !== '' && $createTimeMin !== null) {
            $query->where('create_time', '>=', $createTimeMin);
        }
        if ($createTimeMax !== '' && $createTimeMax !== null) {
            $query->where('create_time', '<=', $createTimeMax);
        }

        $total = $query->count();
        $list = $query->page($page, $limit)->select()->toArray();
        $totalPage = $limit > 0 ? (int) ceil($total / $limit) : 0;

        return $this->success([
            'list'          => $list,
            'total_count'  => $total,
            'total_page'   => $totalPage,
            'current_page' => $page,
            'limit'        => $limit,
        ]);
    }

    /**
     * 游玩记录
     * GET /api/user/playGameRecord
     * header: token（由 TokenMiddleware 注入 request->player_id）
     * 参数: page 页码（默认1）, limit 每页条数（默认10）, create_time_min/create_time_max 创建时间范围（可选）
     */
    public function playGameRecord(Request $request): Response
    {
        $userId = (int) ($request->player_id ?? 0);
        $page = (int) $request->post('page', 1);
        $limit = (int) $request->post('limit', 10);
        if ($page < 1) {
            $page = 1;
        }
        if ($limit < 1) {
            $limit = 10;
        }

        $query = DicePlayRecord::where('player_id', $userId)->order('id', 'desc');

        $createTimeMin = $request->post('create_time_min', '');
        $createTimeMax = $request->post('create_time_max', '');
        if ($createTimeMin !== '' && $createTimeMin !== null) {
            $query->where('create_time', '>=', $createTimeMin);
        }
        if ($createTimeMax !== '' && $createTimeMax !== null) {
            $query->where('create_time', '<=', $createTimeMax);
        }

        $total = $query->count();
        $list = $query->page($page, $limit)->select()->toArray();
        $totalPage = $limit > 0 ? (int) ceil($total / $limit) : 0;

        return $this->success([
            'list'          => $list,
            'total_count'  => $total,
            'total_page'   => $totalPage,
            'current_page' => $page,
            'limit'        => $limit,
        ]);
    }
}
