<?php

namespace App\Game\Services;

use App\Game\GlobalUserInfo;
use App\Http\helper\NumConfig;
use App\Models\AccountsInfo;
use App\Notification\TelegramBot;
use App\Util;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

class LuckyStreakService
{
    protected $client;
    protected $operatorId;
    protected $operatorName;
    protected $clientId;
    protected $clientSecret;
    protected $apiUrl;
    protected $currency;
    protected $hmacId;
    protected $hmacUser;
    protected $hmacKey;

    public function __construct()
    {
        $this->client = new Client();
        $this->currency = env('CONFIG_24680_CURRENCY');
        $this->operatorId = env('LUCKYSTREAK_OPERATOR_ID', '526');
        $this->operatorName = env('LUCKYSTREAK_OPERATOR_NAME', 'AEG');
        $this->clientId = env('LUCKYSTREAK_CLIENT_ID', 'AEG_operator');
        $this->clientSecret = env('LUCKYSTREAK_CLIENT_SECRET', 'X6vuibvYJI2Z9NglbzZE');
        $this->apiUrl = env('LUCKYSTREAK_API_URL', 'https://integ.livepbt.com');
        $this->hmacId = env('LUCKYSTREAK_HMAC_ID', 'AEG1');
        $this->hmacUser = env('LUCKYSTREAK_HMAC_USER', 'AEGhmac1');
        $this->hmacKey = env('LUCKYSTREAK_HMAC_KEY', 'WcVIR7szsyXNPstaY2JX');
    }

    public function callSubApi($username,$request)
    {
        Util::WriteLog('luckystreak_validate','callsubapi');
        $apiurl=ServerService::GetApiByGUID($username);

        try {
            // 获取当前请求的 GET 和 POST 数据
//            $getData = $request->query(); // 获取 GET 数据
            $postData = $request->post(); // 获取 POST 数据

            $response = $this->client->post( $apiurl . $_SERVER['REQUEST_URI'], [
                'verify'=>false,
                //                'query' => $getData, // 传递 GET 数据
                'form_params' => $postData, // 传递 POST 数据
            ]);
            $res=json_decode($response->getBody(),true);
            Util::WriteLog('luckystreak_validate',$res);
            return $res;
        } catch (RequestException $e) {
            return $this->handleRequestException($e);
        }
    }

    private function handleRequestException(\Exception $e)
    {
//        TelegramBot::getDefault()->sendMsgWithEnv($e->getMessage().$e->getTraceAsString());
    }

    /**
     * 获取授权令牌
     *
     * @return string|null
     */
    public function getAuthToken()
    {
        try {
            // 构建凭证字符串
            $credentialsBase = $this->operatorId . ':' . $this->clientId . ':' . $this->clientSecret;
            $credentials = base64_encode($credentialsBase);

            // 请求授权令牌
            $response = $this->client->post('https://integ-api-ids.livepbt.com/ids/connect/token', [
                'verify' => false,
                'headers' => [
                    'Content-Type' => 'application/x-www-form-urlencoded',
                    'Authorization'=>'Basic QUVHX29wZXJhdG9yOlg2dnVpYnZZSkkyWjlOZ2xielpF'
                ],
                'form_params' => [
                    'grant_type' => 'operator_authorization',
                    'scope' => 'operator offline_access',
                    'operator_name' => 'AEG'
                ]
            ]);

            $result = json_decode($response->getBody(), true);
            $token = $result['access_token'] ?? null;

            if ($token) {
                // 缓存令牌一段时间以减少API调用
                $expiresIn = $result['expires_in'] ?? 3600;
                Redis::setex('luckystreak_token', $expiresIn - 60, $token);
            }

            return $token;

        } catch (\Exception $e) {
            Util::WriteLog('luckystreak_error', $e->getMessage());
            return null;
        }
    }

    /**
     * 获取缓存的令牌或请求新令牌
     *
     * @return string|null
     */
    public function getCachedAuthToken()
    {
        // 尝试从缓存获取令牌
        $token = Redis::get('luckystreak_token');

        // 如果缓存中没有令牌或令牌已过期，请求新令牌
        if (!$token) {
            $token = $this->getAuthToken();
        }

        return $token;
    }

    /**
     * 获取游戏列表
     *
     * @return array
     */
    public function getGamesList()
    {
        try {
            // 获取授权令牌
            $token = $this->getCachedAuthToken();
            if (!$token) {
                throw new \Exception("Failed to get authorization token");
            }

            // 调用游戏列表API
            $response = $this->client->post($this->apiUrl . '/lobby/api/v4/lobby/games', [
                'verify' => false,
                'headers' => [
                    'Authorization' => 'Bearer ' . $token,
                    'Content-Type' => 'application/json'
                ],
                'json' => [
                    'data' => [
                        'Open' => true,
                        'GameTypes' => [],
                        'Currencies' => []
                    ]
                ]
            ]);

            return json_decode($response->getBody(), true);

        } catch (\Exception $e) {
            Util::WriteLog('luckystreak_error', $e->getMessage());
            return ['error' => $e->getMessage()];
        }
    }
    public function getJackpot()
    {
        try {
            // 获取授权令牌
            $token = $this->getCachedAuthToken();
            if (!$token) {
                throw new \Exception("Failed to get authorization token");
            }

            // 调用游戏列表API
            $response = $this->client->post($this->apiUrl . '/lobby/api/v4/lobby/jackpots', [
                'verify' => false,
                'headers' => [
                    'Authorization' => 'Bearer ' . $token,
                    'Content-Type' => 'application/json'
                ],
                'json' => [
                ]
            ]);

            return json_decode($response->getBody(), true);

        } catch (\Exception $e) {
            Util::WriteLog('luckystreak_error', $e->getMessage());
            return ['error' => $e->getMessage()];
        }
    }

    /**
     * 获取游戏启动URL的HTML
     *
     * @param string $gameId
     * @param string $globalUid
     * @param string $ipAddress
     * @param string $language
     * @return string
     */
    public function getLaunchURLHTML($gameId,$globalUid, $ipAddress, $language)
    {
        try {
            // 获取游戏类型（如果需要）
            $gameType = $this->getGameTypeById($gameId);

            // 使用GlobalUID作为AuthCode参数
            // 使用正确的启动URL格式
            $launchURL = "https://m.integ.livepbt.com/?PlayerName={$globalUid}&OperatorName=AEG&AuthCode={$globalUid}&GameId={$gameId}&GameType={$gameType}&LimitsGroupId=67efe1d102d4c16717303002";


            // 添加语言参数
            if ($language) {
                $launchURL .= "&language={$language}";
            }

            // 返回HTML重定向脚本
            return "<script>window.location.href='{$launchURL}';</script>";

        } catch (\Exception $e) {
            Util::WriteLog('luckystreak_error', $e->getMessage());
            return "<script>alert('System error: " . $e->getMessage() . "');</script>";
        }
    }

    /**
     * 根据游戏ID获取游戏类型
     *
     * @param string $gameId
     * @return string|null
     */
    private function getGameTypeById($gameId)
    {
        // 基本游戏类型映射
        $gameTypes = [
            '3' => 'Roulette',
            '4' => 'Blackjack',
            '2' => 'Baccarat',
            // 可以添加更多游戏类型映射
        ];

        return $gameTypes[$gameId] ?? null;
    }

    /**
     * 验证HMAC签名（用于出站请求）
     *
     * @param array $data
     * @param string $signature
     * @return bool
     */
    public function verifyHmacSignature($data, $signature)
    {
        // 根据LuckyStreak API文档实现HMAC验证逻辑
        // 按照文档附录B的规范实现

        // 1. 获取完整请求URL中的路径部分（不包含域名和查询参数）
        $path = $data['path'] ?? '';
        unset($data['path']);

        // 2. 获取请求方法
        $method = $data['method'] ?? 'POST';
        unset($data['method']);

        // 3. 获取请求时间戳
        $timestamp = $data['timestamp'] ?? '';
        if (empty($timestamp)) {
            return false;
        }
        unset($data['timestamp']);

        // 4. 获取随机nonce
        $nonce = $data['nonce'] ?? '';
        if (empty($nonce)) {
            return false;
        }
        unset($data['nonce']);

        // 获取ext和hash
        $ext = '';
        if (isset($data['ext'])) {
            $ext = $data['ext'];
            unset($data['ext']);
        }

        $hash = '';
        if (isset($data['hash'])) {
            $hash = $data['hash'];
            unset($data['hash']);
        }

        // 主机名和端口
        $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'euapi.24680.org';
        $port = '443'; // 假设使用HTTPS

        // 5. 构建规范化请求字符串
        $normalized = "hawk.1.header\n" .
                     $timestamp . "\n" .
                     $nonce . "\n" .
                     $method . "\n" .
                     $path . "\n" .
                     $host . "\n" .
                     $port . "\n";

        // 6. 如果有请求体，添加请求体内容的哈希
        if (isset($data['body']) && !empty($data['body'])) {
            $body = $data['body'];

            // 如果是JSON字符串，尝试解码并重新编码，确保格式一致
            if (is_string($body) && json_decode($body) !== null) {
                $bodyObj = json_decode($body, true);
                if (is_array($bodyObj)) {
                    $body = json_encode($bodyObj);
                }
            } elseif (is_array($body)) {
                $body = json_encode($body);
            }

            // 如果已提供的hash值，使用它
            if (!empty($hash)) {
                $normalized .= $hash . "\n";
            } else {
                // 否则计算body的hash
                $bodyHash = base64_encode(hash('sha256', $body, true));
                $normalized .= $bodyHash . "\n";
            }
        } else {
            $normalized .= "\n"; // 如果没有请求体，添加空行
        }

        // 7. 如果有ext，添加ext
        if (!empty($ext)) {
            $normalized .= $ext . "\n";
        } else {
            $normalized .= ''; // 如果没有ext，添加空字符串
        }

        // 8. 使用HMAC-SHA256生成签名
        $calculatedSignature = base64_encode(hash_hmac('sha256', $normalized, $this->hmacKey, true));

        // 9. 比较签名
//        Util::WriteLog('luckystreak_hmac', [
//            'normalized' => $normalized,
//            'calculated' => $calculatedSignature,
//            'received' => $signature,
//            'hmacKey' => $this->hmacKey
//        ]);

        return $signature === $calculatedSignature;
    }

    public function generateHmacSignature($data, $body = null)
    {

//        $data=['path' => '',
//         'method' => '',
//         'timestamp' => '',
//         'nonce' => ''];
        // 生成时间戳（毫秒级）
//        $timestamp = (string)round(microtime(true) * 1000);

        // 生成随机nonce
//        $nonce = uniqid('', true);

        extract($data);

        // 主机名和端口
        $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'euapi.24680.org';
        $port = '443'; // 假设使用HTTPS

        // 请求标识符 (根据文档使用hawk.1.response)
        $type = "hawk.1.response";

        // 构建规范化请求字符串
        $normalized = $type . "\n" .
                     $timestamp . "\n" .
                     $nonce . "\n" .
                     $method . "\n" .
                     $path . "\n" .
                     $host . "\n" .
                     $port . "\n";

        // 如果有请求体，添加请求体的哈希
        $bodyHash = '';
        if (!empty($body)&&false) {
            // 如果是JSON字符串，尝试解码并重新编码，确保格式一致
            if (is_string($body) && json_decode($body) !== null) {
                $bodyObj = json_decode($body, true);
                if (is_array($bodyObj)) {
                    $body = json_encode($bodyObj);
                }
            } elseif (is_array($body)) {
                $body = json_encode($body);
            }

            $bodyHash = base64_encode(hash('sha256', $body, true));
            $normalized .= $bodyHash . "\n";
        } else {
            $normalized .= "\n"; // 如果没有请求体，添加空行
        }

        // 添加ext（根据文档使用X-Request-Header-To-Protect:secret）
        $ext = "X-Request-Header-To-Protect:secret";
        $normalized .= $ext ."\n";

        // 使用HMAC-SHA256生成签名
        $signature = base64_encode(hash_hmac('sha256', $normalized, $this->hmacKey, true));

//        Util::WriteLog('luckystreak_hmac', [
//            'normalized' => $normalized,
//            'signature' => $signature,
//            'body' => $body,
//            'bodyHash' => $bodyHash,
//            'header'=>[ 'Server-Authorization' => 'hawk mac="' . $signature . '", ext="' . $ext . '"']
//        ]);

        // 返回Server-Authorization头（根据文档）
        return [
            'Server-Authorization' => 'hawk mac="' . $signature . '", ext="' . $ext . '"'
        ];
    }

    /**
     * 获取第三方游戏提供商游戏列表
     *
     * @return array
     */
    public function getProviderGamesList()
    {
        try {
            // 获取授权令牌
            $token = $this->getCachedAuthToken();
            if (!$token) {
                throw new \Exception("Failed to get authorization token");
            }

            // 调用Provider游戏列表API
            $response = $this->client->post($this->apiUrl . '/lobby/api/v4/lobby/providergames', [
                'verify' => false,
                'headers' => [
                    'Authorization' => 'Bearer ' . $token,
                    'Content-Type' => 'application/json'
                ],
                'json' => [
                    'data' => [
                        'Open' => true,
                        'GameTypes' => [],
                        'Currencies' => []
                    ]
                ]
            ]);

            return json_decode($response->getBody(), true);

        } catch (\Exception $e) {
            Util::WriteLog('luckystreak_error', $e->getMessage());
            return ['error' => $e->getMessage()];
        }
    }
}

