<?php

require_once "common/GameGameConfig.php";

use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use think\facade\Db;
use app\model\UserIdAssignModel;

/// 加密密钥
$GLOBALS['token_key_secret'] = "z.1i8L?Ld+ovuA4r%4YZrz?w1Y%-NYvlrJ=TqV$[W[5=B#C[=l2gHV8gJ,DhZc";
/// COOKIE 有效期
$GLOBALS['cookieExpire'] = 60 * 60 * 24 * 3;

// 全局默认RTP值
$GLOBALS['defaultRTPValue'] = 97;

/**
 * 响应成功json
 */
if(!function_exists('json_success')){
    function json_success($data = [], $message = "", $code = 0){
        return json([
            'state' => 1,
            'code' => $code,
            'data' => $data,
            'message' => $message ?? ""
        ]);
    }
}

/**
 * 响应失败json
 */
if(!function_exists('json_error')){
    function json_error($data = [], $message = "", $code = 0){
        return json([
            'state' => 0,
            'code' => $code,
            'data' => $data,
            'message' => $message ?? ""
        ]);
    }
}

/**
 * 获取用户真实请求IP
 * 使用ThinkPHP内置的Request::ip()方法
 *
 * @return string 返回客户端真实IP地址
 */
if(!function_exists('getClientIp')){
    function getClientIp() {
        return \think\facade\Request::ip();
    }
}

/**
 * 生成JWT Token
 *
 * @param array $data 待加密数据
 * @param int $expire 过期时间（秒），0表示使用默认过期时间
 * @return string
 */
if(!function_exists('generateToken')){
    function generateToken($data = [], $expire = 0){
        $payload = [
            'exp' => time() + ($expire > 0 ? $expire : $GLOBALS['cookieExpire']), // 有效期
            'iat' => time(), // 签发时间
        ];
        $payload = array_merge($payload, $data);
        $token = JWT::encode($payload, $GLOBALS['token_key_secret'], 'HS256');
        return $token;
    }
}

/**
 * 解析JWT Token
 *
 * @param string $token JWT Token字符串
 * @return array|null 解析成功返回payload数组，失败返回null
 */
if(!function_exists('parseToken')){
    function parseToken($token) {
        try {
            if (empty($token)) {
                return null;
            }
            
            // 使用JWT库解析token
            $decoded = JWT::decode($token, new Key($GLOBALS['token_key_secret'], 'HS256'));
            
            // 转换为数组
            $payload = (array) $decoded;
            
            // 检查是否过期
            if (isset($payload['exp']) && $payload['exp'] < time()) {
                return null;
            }
            
            return $payload;
            
        } catch (\Firebase\JWT\ExpiredException $e) {
            // Token已过期
            return null;
        } catch (\Firebase\JWT\SignatureInvalidException $e) {
            // 签名无效
            return null;
        } catch (\Firebase\JWT\BeforeValidException $e) {
            // Token尚未生效
            return null;
        } catch (\Exception $e) {
            // 其他异常
            return null;
        }
    }
}

/**
 * 验证Token是否有效
 *
 * @param string $token JWT Token字符串
 * @return bool
 */
if(!function_exists('verifyToken')){
    function verifyToken($token) {
        return parseToken($token) !== null;
    }
}

/**
 * 检查用户登录状态
 *
 * @return array|null 登录成功返回用户信息数组，失败返回null
 */
if(!function_exists('checkUserLogin')){
    function checkUserLogin() {
        $token = \think\facade\Cookie::get('auth_token');
        if (!$token) {
            return null;
        }
        
        return parseToken($token);
    }
}

/**
 * 获取当前登录用户ID
 */
if(!function_exists('getUserId')){
    function getUserId(): int {
        $userInfo = checkUserLogin();
        return $userInfo ? (int)$userInfo['user_id'] : 0;
    }
}

/**
 * 获取当前登录用户角色ID
 */
if(!function_exists('getUserRoleId')){
    function getUserRoleId(int $userId): int {
        if (!$userId) {
            return 0;
        }
        
        $user = \app\model\UserModel::where('user_id', $userId)->find();
        return $user ? (int)$user->user_role : 0;
    }
}

/**
 * 检查用户权限
 *
 * @param array $user 用户信息数组
 * @param string $controller 控制器名称
 * @param string $action 操作名称
 * @param bool $checkIp 是否检查IP白名单，默认false
 * @return bool 有权限返回true，无权限返回false
 */
if(!function_exists('checkPermission')){
    function checkPermission($user, $controller, $action, $checkIp = false) {
        $userId = is_array($user) ? (int)$user['user_id'] : 0;
        if (!$userId) {
            return false;
        }
        
        // 使用PermissionService统一权限检查
        $hasPermission = \app\service\PermissionService::checkPermission($userId, $controller, $action);
        
        // 如果有权限且需要检查IP，则进一步验证IP白名单
        if ($hasPermission && $checkIp) {
            return checkUserIpWhiteList($user);
        }
        
        return $hasPermission;
    }
}

/**
 * 检查用户IP白名单
 *
 * @param array $user 用户信息数组
 * @return bool IP在白名单中返回true，否则返回false
 */
if(!function_exists('checkUserIpWhiteList')){
    function checkUserIpWhiteList($user) {
        // 获取用户完整信息
        $userModel = \app\model\UserModel::where('user_id', $user['user_id'])
            ->where('merchant_id', $user['merchant_id'])
            ->find();
            
        if (!$userModel) {
            return false;
        }
        
        // 获取客户端IP
        $clientIp = getClientIp();
        
        // 检查IP白名单
        return \app\service\IpWhiteListService::checkIpWhiteList($clientIp, $userModel->white_list_ip);
    }
}

/**
 * 检查用户登录状态并验证IP白名单
 *
 * @param bool $checkIp 是否检查IP白名单，默认false
 * @return array|null 验证通过返回用户信息数组，失败返回null
 */
if(!function_exists('checkUserLoginWithIp')){
    function checkUserLoginWithIp($checkIp = false) {
        $user = checkUserLogin();
        if (!$user) {
            return null;
        }
        
        // 如果需要检查IP白名单
        if ($checkIp && !checkUserIpWhiteList($user)) {
            return null;
        }
        
        return $user;
    }
}

/**
 * 获取IP地址的地理位置信息
 *
 * @param string $ip IP地址，如果为空则获取当前请求的IP
 * @param bool $formatted 是否返回格式化的数据
 * @return array 返回IP地理位置信息
 */
if(!function_exists('getIpLocation')){
    function getIpLocation($ip = '', $formatted = false) {
        if (empty($ip)) {
            $ip = getClientIp();
        }
        
        try {
            $ipService = \app\service\IpLocationService::getInstance();
            
            if ($formatted) {
                $result = $ipService->getLocationFormatted($ip);
            } else {
                $result = $ipService->getLocation($ip);
            }
            
            if ($result['status']) {
                return $result['data'];
            } else {
                return [
                    'ip' => $ip,
                    'location' => '未知'
                ];
            }
        } catch (\Exception $e) {
            return [
                'ip' => $ip,
                'location' => '查询失败'
            ];
        }
    }
}

/**
 * 批量获取IP地址的地理位置信息
 *
 * @param array $ips IP地址数组
 * @param bool $formatted 是否返回格式化的数据
 * @return array 返回IP地理位置信息数组
 */
if(!function_exists('batchGetIpLocation')){
    function batchGetIpLocation(array $ips, $formatted = false) {
        try {
            $ipService = \app\service\IpLocationService::getInstance();
            
            if ($formatted) {
                return $ipService->batchGetLocationFormatted($ips);
            } else {
                return $ipService->batchGetLocation($ips);
            }
        } catch (\Exception $e) {
            $results = [];
            foreach ($ips as $ip) {
                $results[$ip] = [
                    'status' => false,
                    'message' => '查询失败',
                    'data' => null
                ];
            }
            return $results;
        }
    }
}

/**
 * 分配用户id
 */
if(!function_exists('assignUserId')) {
    function assignUserId(): int|false
    {
        $data = [
            'status' => 1,
            'user_id' => Db::raw('LAST_INSERT_ID(user_id)'),
        ];

        try {
            $affectedRows = UserIdAssignModel::where('status', 0)->limit(1)->update($data);

            if ($affectedRows > 0) {
                $result = Db::query('SELECT LAST_INSERT_ID()');

                if (!empty($result) && isset($result[0])) {
                    $assignedId = array_values($result[0])[0] ?? null;

                    if ($assignedId !== null) {
                        return (int)$assignedId;
                    }
                }
            }
        } catch (Throwable $e) {
            return 0;
        }

        return 0;
    }
}

/**
 * 获取游戏RTP
 */
if(!function_exists('calculateRTP')) {
    function calculateRTP($totalWin, $totalBet): int|float
    {
        $rtp = 0;
        if (!empty($totalBet)) {
            $rtp = (float)bcmul(bcdiv((string)$totalWin, (string)$totalBet, 4), '100', 2);
        }
        return $rtp;
    }
}
