<?php


namespace App\Http\Controllers\Game;


use App\Facade\TableName;
use App\Game\GlobalUserInfo;
use App\Http\helper\NumConfig;
use App\Models\Account\UserBlacklist;
use App\Models\AccountsInfo;
use App\Models\Treasure\GameScoreLocker;
use App\Notification\TelegramBot;
use App\Util;
use App\Utility\SetNXLock;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Validator;

class WithDrawInfoController
{



    public function FreeWithDrawInfo(Request $request)
    {
        $user = $request->user();
        $userScoreData = GlobalUserInfo::getScoreDataByUserID($user->UserID);
        
        // 获取用户已提现的总金额（State = 2 表示成功）
        $withdrawnAmount = DB::table('QPAccountsDB.dbo.OrderWithDraw')
            ->where('UserID', $user->UserID)
            ->where('State', 2)
            ->lock('WITH(NOLOCK)')
            ->sum('WithDraw') ?? 0;
        
        if(!$userScoreData['Recharge']){
            $totalWithdraw = max($userScoreData['InsureScore'],40);
            if($userScoreData['InsureScore']<40){
                //第一种状态，我免费领了10块钱，但是金额不足40，点进去页面填信息后点击提现，提示我去玩游戏
                return apiReturnSuc(['state' => 1, 'total' => $totalWithdraw,'InsureScore' => $userScoreData['InsureScore'], 'withdrawn' => $withdrawnAmount]);
            }else{
                //第二种状态，我免费金额足够40，提现按钮会点亮，告知用户点击进去
                return apiReturnSuc(['state' => 2, 'total' => $totalWithdraw,'InsureScore' => $userScoreData['InsureScore'], 'withdrawn' => $withdrawnAmount]);
            }
        }else{
            //第四种状态，VIP状态下，金额不足了，进度条颜色红色，按钮灰色（不可点击），次日整个消失
            if($userScoreData['InsureScore']<10){
                return apiReturnSuc(['state' => 4, 'total' => max($userScoreData['InsureScore'],40),'InsureScore' => max($userScoreData['InsureScore'],40), 'withdrawn' => $withdrawnAmount]);
            }else{
                //第三种状态，进去完成了充值未提现，提现按钮会高光，引导用户完成提现
                return apiReturnSuc(['state' => 3, 'total' => max($userScoreData['InsureScore'],40),'InsureScore' => max($userScoreData['InsureScore'],40), 'withdrawn' => $withdrawnAmount]);
            }
        }
    }

    public function WithDrawRecord(Request $request)
    {

        $user = $request->user();
        $UserID=$user->UserID;


//        $paypass = $request->input('paypass');
//        if (!empty($user->InsurePass)&&!Hash::check($paypass,$user->InsurePass)) {
//            return apiReturnFail(['web.user.paypass_fail', 'A senha original está errada, digite-a novamente.'], '', 2);
//        }

        $scoreType = intval($request->input('score_type', -1));
        if (!in_array($scoreType, [-1, 0, 1], true)) {
            return apiReturnFail(['web.withdraw.params_error', 'score_type must be -1, 0 or 1'], [], 422);
        }
        $sort = strtolower($request->input('sort', 'desc'));
        $sort = in_array($sort, ['asc', 'desc']) ? $sort : 'desc';
        $sortBy = strtolower($request->input('sort_by', 'createdate'));
        $pageSize = intval($request->input('page_size', 10));
        if ($pageSize <= 0) {
            $pageSize = 100;
        }

        $query = DB::table('QPAccountsDB.dbo.OrderWithDraw')
            ->where('UserID', $UserID);

        if ($scoreType !== -1) {
            $query->where('score_type', $scoreType);
        }

        $allowedSortColumns = [
            'withdraw' => 'WithDraw',
            'createdate' => 'CreateDate',
        ];
        $sortColumn = $allowedSortColumns[$sortBy] ?? 'CreateDate';

        $list = $query
            ->selectRaw("CreateDate,OrderId,[State],WithDraw,ServiceFee,PixType,score_type")
            ->where('CreateDate', '>=', date('Y-m-d', strtotime('-30 day')))
            ->orderBy($sortColumn, $sort)
            ->paginate($pageSize);
        return apiReturnSuc($list);
    }

    public function GetWithDrawBaseInfo(Request $request)
    {
        $user = $request->user();
        $UserID=$user->UserID;


//        $paypass = $request->input('paypass');
//
//        if (empty($user->InsurePass)||!Hash::check($paypass,$user->InsurePass)) {
//            return apiReturnFail(['web.user.paypass_fail', 'A senha original está errada, digite-a novamente.'], '', 2);
//        }

        $dbh = DB::connection()->getPdo();

        $sql="DECLARE  @return_value int
        set nocount on use QPAccountsDB
        EXEC  @return_value = GSP_GR_GetWithDrawBaseInfo '$UserID'
        SELECT 'ReturnValue' = @return_value";

//        echo $sql;die;
        $stmt = $dbh->prepare($sql);

        $stmt->execute();

        $retval = $stmt->fetch(\PDO::FETCH_ASSOC);

        $retval['srate']=env('CONFIG_24680_RATE',1);
        // 获取绑定手机号
        $phone = DB::table(TableName::QPAccountsDB() . 'AccountPhone')->where('UserID', $UserID)->value('PhoneNum');
        $phone = trim($phone);
        // 去掉国家号前缀
        $countryCode = (string) env('COUNTRY_CODE', '1');
        if ($countryCode !== '' && strpos($phone, $countryCode) === 0) {
            $phone = substr($phone, mb_strlen($countryCode));
        }
        $retval['bind_phone'] = $phone;
        $hasSuccessWithdraw = DB::table('QPAccountsDB.dbo.OrderWithDraw')
            ->lock('WITH(NOLOCK)')
            ->where('UserID', $UserID)
            ->where('State', 2)
            ->exists();
        $retval['has_success_withdraw'] = $hasSuccessWithdraw;

        
        if (Redis::exists('withdraw_info_time_' . $UserID)) {
            $lastTime = Redis::get('withdraw_info_time_' . $UserID);
            $retval['withdraw_info_update_by_phone'] = true;
            $retval['withdraw_info_update_time_pass'] = time() - $lastTime;
        } else {
            $retval['withdraw_info_update_by_phone'] = false;
            $retval['withdraw_info_update_time_pass'] = 0;
        }
        
        return apiReturnSuc($retval);
    }
    public function GoWithDraw(Request $request)
    {
        $user = $request->user();
        $UserID=$user->UserID;


//        $paypass = $request->input('paypass');
//
//        if (empty($user->InsurePass)||!Hash::check($paypass,$user->InsurePass)) {
//            return apiReturnFail(['web.user.paypass_fail', 'A senha original está errada, digite-a novamente.'], '', 2);
//        }

        $exists = UserBlacklist::where('UserID', $UserID)->first();
        if ($exists){
            return apiReturnFail(['web.withdraw.try_again_later','User In Control']);
        }


        $score=$request->input('score',0);
        if(!$score||is_float($score)||$score<=0){
            return apiReturnFail(['web.withdraw.score_fail', 'Amount must be an integer value.']);
        }
        $redisKey = 'withdraw_'.$UserID;
        if (!SetNXLock::getExclusiveLock($redisKey)) {
            return apiReturnFail(['web.withdraw.try_again_later','Tente novamente mais tarde']);
        }

        GameScoreLocker::where('UserID',$UserID)->delete();

        $dbh = DB::connection()->getPdo();

//        $score=$score*NumConfig::NUM_VALUE;

        $sql="DECLARE  @return_value int
        set nocount on use QPAccountsDB
        EXEC  @return_value = GSP_GR_GetWithDraw20260312 '$UserID','$score'
        SELECT 'ReturnValue' = @return_value";

//        echo $sql;die;
        $stmt = $dbh->prepare($sql);

        $stmt->execute();

        SetNXLock::release($redisKey);

        $retval = $stmt->fetch(\PDO::FETCH_ASSOC);

        try {


//        set @ret = 1	--可提额度不足
//        set @ret = 2	--低于最低可提现金额
//        set @ret = 3	--高于最高可提现金额
//        set @ret = 4	--超过每天提现次数上限
//        set @ret = 5	--身上钱不够
//        set @ret = 6	--开在游戏里面
//        set @ret = 7	--未充值的用户TX额度
            if (isset($retval['ReturnValue'])) {
                $ReturnValue = $retval['ReturnValue'];
                // set @ret = 1 -- Insufficient withdrawal amount
// set @ret = 2 -- Lower than the minimum withdrawal amount
// set @ret = 3 -- Higher than the maximum withdrawal amount
// set @ret = 4 -- Exceeded the daily withdrawal limit
// set @ret = 5 -- Not enough money on hand
// set @ret = 6 -- Opened in the game
// set @ret = 7 -- Undeposited user TX amount
                $errors = [
                    [],
                    ['web.withdraw.no_withdraw_value', "The withdrawable amount is not enough"],
                    ['web.withdraw.too_low', 'Lower than the minimum withdrawal amount'],
                    ['web.withdraw.too_high', 'Higher than the maximum withdrawal amount'],
                    ['web.withdraw.day_max', 'Exceeded the daily withdrawal limit'],
                    ['web.withdraw.no_enouth_score', 'Not enough money on hand'],
                    ['web.withdraw.in_game', 'Sorry, You\'re in game for now'],
                    ['web.withdraw.no_deposit', ' You need deposit first!'],
                ];
                return apiReturnFail($errors[$ReturnValue], [], $ReturnValue == 7 ? 777 : 301);
            }else{
                return apiReturnSuc($retval);
            }
        }catch (\Exception $e){
            TelegramBot::getDefault()->sendProgramNotify("WithDraw Error:", var_export($retval,true).':'.$e->getTraceAsString());
            return apiReturnSuc($retval);
        }
    }
    public function saveCpf(Request $request)
    {
//        $user = $request->user();
//        $UserID=$user->UserID;
//
//        $account = $request->Account ?: '';
//        $phone = $request->Phone ?: '';
//        $email = $request->Email ?: '';
//        $PixNum = $request->PixNum ?: '';
//
//        if(!Util::validateCpf($PixNum)){
//            return apiReturnFail(['withdraw.account.tip.cpf_error','Cpf error format']);
//        }
//
//        $redisKey = 'Api_updateAccountsPayInfo_'.$UserID;
//        $lock = SetNXLock::getExclusiveLock($redisKey);
//        if (!$lock) {
//            return apiReturnFail(['web.withdraw.try_again_later','Tente novamente mais tarde']);
//        }
//        $exist = DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')->where('UserID', $UserID)->first();
//
//        if ($exist) {
//            DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')->where('UserID', $UserID)->update(['PixNum' => $PixNum]);
//        } else {
//
//            $data = ['BankUserName' => $account, 'PhoneNumber' => $phone, 'EmailAddress' => $email, 'UserID' => $UserID, 'PixNum' => $PixNum, 'Achieves' => '', 'HistoryWithDraw' => 0];
//            DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
//                ->insert($data);
//        }
//        SetNXLock::release($redisKey);
        return apiReturnSuc();
    }
    public function MexWithDrawInfo(Request $request)
    {
        $user = $request->user();
        $UserID=$user->UserID;
        $paypass = $request->input('paypass');


        $PixType = $request->input('cbPixType');;
        $BankNO = $request->input('account');
        $AccountsBank = $request->input('account');
        $BankUserName = $request->input('userName');
        $PhoneNumber = $request->input('phone');
        $EmailAddress = $request->input('email');
        $IFSCNumber = $request->input('IFSCNumber');
//        $PANNumber = $request->input('PAN');
//        $AdhaarNumber = $request->input('adhaar');
//        $BranchBank = $request->input('branceBank');
        $BranchBank = $request->input('bank');//银行编号
        $PixNum = $request->input('account');

        Util::WriteLog("mexwithdraw",$request->all());
        if(isset($EmailAddress)&&!empty($EmailAddress)){
            $validator = Validator::make(
                ['email' => $EmailAddress],
                ['email' => 'required|email']
            );

            if ($validator->fails()) {
                return apiReturnFail(['web.user.email_fail','Wrong email format']);
            }
        }
        if (!$AccountsBank || $AccountsBank == 'undefined') {
            return apiReturnFail(['web.bank.account_empty', 'The bank account cannot be empty']);
        }

        if (!(strlen($AccountsBank) == 16 || strlen($AccountsBank) == 18)) {
            return apiReturnFail(['web.bank.account_invalid_length', 'The bank number must have 16 or 18 digits']);
        }

        if (!(strlen($IFSCNumber) == 18 && $IFSCNumber)) {
            return apiReturnFail(['web.bank.clabe_invalid_length', 'The Clabe number must have 18 digits']);
        }

        if (!$BankUserName || $BankUserName == 'undefined') {
            return apiReturnFail(['web.bank.username_empty', 'The name cannot be empty']);
        }

        if (!$BranchBank || $BranchBank == 'undefined') {
            return apiReturnFail(['web.bank.branch_empty', 'The branch code cannot be empty']);
        }

        if (strlen($AccountsBank) == 16) {
            $PixType = 2;
        }

        if (strlen($AccountsBank) == 18) {
            $PixType = 1;
        }

        $redisKey = 'withDrawInfo_withDrawInfo_' . $UserID;
        if (!SetNXLock::getExclusiveLock($redisKey)) {
            return apiReturnFail(['web.bank.try_again_later', 'Please try again later']);
        }

        if (!$UserID) {
            Log::info('miss UserID', $request->all());
            SetNXLock::release($redisKey);
            return apiReturnFail(['web.bank.missing_userid', 'params error']);
        }

        if (empty($PixType)) {
            SetNXLock::release($redisKey);
            return apiReturnFail(['web.bank.pix_type_missing', 'The PIX type is missing']);
        }

// 验证PixNum绑定次数
        if (!empty($PixNum)) {
            $BindCount = DB::table(TableName::QPRecordDB() . 'RecordBankCardBind')
                ->where('BankCard', $PixNum)
                ->lock('WITH(NOLOCK)')
                ->count();
            if ($BindCount >= 3) {
                SetNXLock::release($redisKey);
                return apiReturnFail(['web.bank.cpf_used_multiple_times', 'The CPF number has been used multiple times and cannot be saved'], [], 302);
            }
        }


        // 验证玩家信息
        if (!empty($user->InsurePass)&&!Hash::check($paypass,$user->InsurePass)) {
            return apiReturnFail(['web.user.paypass_fail', 'A senha original está errada, digite-a novamente.'], '', 2);
        }


        if ($PixType < 10 && false) {
            $data = compact('PixType', 'BankUserName', 'PhoneNumber', 'EmailAddress', 'PixNum');
        } else {
            $data = compact('PixType', 'BankUserName','IFSCNumber', 'PhoneNumber', 'EmailAddress','BankNO', 'AccountsBank','BranchBank','PixNum');
            $PixNum = $BankNO;
        }

        foreach ($data as $key => &$val) {
            $data[$key] = trim($val);
        }
        unset($val);


        $AccountWithDrawInfo = DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
            ->lock('WITH(NOLOCK)')
            ->where('UserID', $UserID)
            ->first();
        if (!$AccountWithDrawInfo) {
            $data['UserID'] = $UserID;
            $data['Achieves'] = 0;
            $data['HistoryWithDraw'] = 0;
            try {
                DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
                    ->where('UserID', $UserID)
                    ->insert($data);
            } catch (\Exception $e) {
                Log::error('insert AccountWithDrawInfo failed', ['data' => $data]);
            }

        } else {
            DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
                ->where('UserID', $UserID)
                ->update($data);
        }

        // 添加绑定记录
        if (empty($AccountWithDrawInfo->PixNum) || $AccountWithDrawInfo->PixNum != $PixNum) {
            try {
                DB::table(TableName::QPRecordDB() . 'RecordBankCardBind')
                    ->insert([
                        'UserID' => $UserID,
                        'BankCard' => $PixNum ?: '',
                        'BindDate' => now()
                    ]);
            } catch (\Exception $e) {
                Log::error('insert RecordBankCardBind failed', ['data' => $data]);
            }

        }
        SetNXLock::release($redisKey);
        return apiReturnSuc();
    }
    public function RuWithDrawInfo(Request $request)
    {
        $user = $request->user();
        $UserID=$user->UserID;
        $paypass = $request->input('paypass');


        $PixType = $request->input('PixType');;
        $BankNO = $request->input('account');

        $BankUserName = $request->input('userName');
        $PhoneNumber = $request->input('phone');
//        $EmailAddress = $request->input('email');
//        $IFSCNumber = $request->input('IFSCNumber');
//        $PANNumber = $request->input('PAN');
//        $AdhaarNumber = $request->input('adhaar');
//        $BranchBank = $request->input('branceBank');
        $BranchBank = $request->input('bank');//银行编号
        $PixNum = $BankNO;
        $AccountsBank = $BankNO;

        Util::WriteLog("ruwithdraw",$request->all());


        if (!$BankUserName || $BankUserName == 'undefined') {
            return apiReturnFail(['web.bank.username_empty', 'The name cannot be empty']);
        }

        if($PixType==1) {
            if (!$AccountsBank || $AccountsBank == 'undefined') {
                return apiReturnFail(['web.bank.account_empty', 'The bank account cannot be empty']);
            }

            if (!(strlen($AccountsBank) == 16 )) {
                return apiReturnFail(['web.bank.account_invalid_length', 'The bank number must have 16  digits']);
            }

//        if (!(strlen($IFSCNumber) == 11 && $IFSCNumber)) {
//            return apiReturnFail(['web.bank.clabe_invalid_length', 'The Clabe number must have 18 digits']);
//        }


        }else{
            if(!$PhoneNumber||strlen($PhoneNumber)!=11){
                return apiReturnFail(['withdraw.account.tip.phone_error', 'The phone number is error']);
            }

            if (!$BranchBank || $BranchBank == 'undefined') {
                return apiReturnFail(['web.bank.branch_empty', 'The branch code cannot be empty']);
            }
        }

        $redisKey = 'withDrawInfo_withDrawInfo_' . $UserID;
        if (!SetNXLock::getExclusiveLock($redisKey)) {
            return apiReturnFail(['web.bank.try_again_later', 'Please try again later']);
        }

        if (!$UserID) {
            Log::info('miss UserID', $request->all());
            SetNXLock::release($redisKey);
            return apiReturnFail(['web.bank.missing_userid', 'params error']);
        }

        if (empty($PixType)) {
            SetNXLock::release($redisKey);
            return apiReturnFail(['web.bank.pix_type_missing', 'The PIX type is missing']);
        }

// 验证PixNum绑定次数
        if (!empty($PixNum)) {
            $BindCount = DB::table(TableName::QPRecordDB() . 'RecordBankCardBind')
                ->where('BankCard', $PixNum)
                ->lock('WITH(NOLOCK)')
                ->count();
            if ($BindCount >= 3) {
                SetNXLock::release($redisKey);
                return apiReturnFail(['web.bank.cpf_used_multiple_times', 'The CPF number has been used multiple times and cannot be saved'], [], 302);
            }
        }


        // 验证玩家信息
        if (!empty($user->InsurePass)&&!Hash::check($paypass,$user->InsurePass)) {
            return apiReturnFail(['web.user.paypass_fail', 'A senha original está errada, digite-a novamente.'], '', 2);
        }



        $data = compact('PixType', 'BankUserName', 'PhoneNumber','BankNO', 'AccountsBank','BranchBank','PixNum');
        $PixNum = $BankNO;

        foreach ($data as $key => &$val) {
            $data[$key] = trim($val);
        }
        unset($val);


        $AccountWithDrawInfo = DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
            ->lock('WITH(NOLOCK)')
            ->where('UserID', $UserID)
            ->first();
        if (!$AccountWithDrawInfo) {
            $data['UserID'] = $UserID;
            $data['Achieves'] = 0;
            $data['HistoryWithDraw'] = 0;
            try {
                DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
                    ->where('UserID', $UserID)
                    ->insert($data);
            } catch (\Exception $e) {
                Log::error('insert AccountWithDrawInfo failed', ['data' => $data]);
            }

        } else {
            DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
                ->where('UserID', $UserID)
                ->update($data);
        }

        // 添加绑定记录
        if (empty($AccountWithDrawInfo->PixNum) || $AccountWithDrawInfo->PixNum != $PixNum) {
            try {
                DB::table(TableName::QPRecordDB() . 'RecordBankCardBind')
                    ->insert([
                        'UserID' => $UserID,
                        'BankCard' => $PixNum ?: '',
                        'BindDate' => now()
                    ]);
            } catch (\Exception $e) {
                Log::error('insert RecordBankCardBind failed', ['data' => $data]);
            }

        }
        SetNXLock::release($redisKey);
        return apiReturnSuc();
    }
    public function withDrawInfo(Request $request)
    {

//        return apiReturnFail('params error');

        $user = $request->user();
        $UserID=$user->UserID;



        // 检查是否有成功的提现记录 (State = 2 表示成功)
        $hasSuccessWithdraw = DB::table('QPAccountsDB.dbo.OrderWithDraw')
            ->lock('WITH(NOLOCK)')
            ->where('UserID', $UserID)
            ->where('State', 2)
            ->exists();

        $limitKey = 'last_withdraw_info_update_' . $UserID;
        if ($hasSuccessWithdraw) {

            if (Redis::exists($limitKey)) {
                return apiReturnFail(['web.withdraw.update_limit', 'You can only update your information once every 24 hours.']);
            }
            $code = $request->input('code');
            if (empty($code)) {
                return apiReturnFail(['web.verify.code_empty', 'Verification code cannot be empty']);
            }

            $phone = DB::table(TableName::QPAccountsDB() . 'AccountPhone')->where('UserID', $UserID)->value('PhoneNum');
            if (empty($phone)) {
                return apiReturnFail(['web.verify.phone_not_bound', 'Phone number not bound']);
            }

            $verifyStatus = \App\Models\GamePhoneVerityCode::verifyCode($phone, $code);
            if ($verifyStatus == 1) {
                return apiReturnFail(['web.verify.code_error', 'Invalid verification code']);
            }
            // 验证通过，清除验证码
            \App\Models\GamePhoneVerityCode::clearPhoneCode($phone);
            // 设置标识，下次修改时弹窗
            Redis::setex('withdraw_info_time_' . $UserID, 30 * 24 * 3600, time());
        } else {
            Redis::del('withdraw_info_time_' . $UserID);
        }

//        $UserID = (int)$request->globalUser->UserID;//$request->input('UserID');
//        $RequestDynamicPass = $request->input('DynamicPass');
        $PixType = $request->input('cbPixType');
        $BankUserName = urldecode($request->input('userName'));
        $EmailAddress = $request->input('email');
        $PixNum = $request->input('PixNum');

        if(!empty($EmailAddress))$EmailAddress=Util::cleanEmptyString($EmailAddress);
        if(!empty($PixNum))$PixNum=Util::cleanEmptyString($PixNum);

        if (!empty($EmailAddress)&&!Util::validateEmail($EmailAddress)) {
            return apiReturnFail(['web.user.email_fail','Wrong email format']);
        }

        $redisKey = 'withDrawInfo_withDrawInfo_'.$UserID;
        if (!SetNXLock::getExclusiveLock($redisKey)) {
            Util::WriteLog("withdrawInfo",[1, $request->all()]);
            return apiReturnFail(['web.withdraw.try_again_later','Tente novamente mais tarde']);
        }

        if (!$UserID) {
            Util::WriteLog("withdrawInfo",[2, $request->all()]);
            Log::info('miss UserID', $request->all());
            SetNXLock::release($redisKey);
            return apiReturnFail(['web.withdraw.params_error','params error']);
        }
        if (empty($PixType)) {
            Util::WriteLog("withdrawInfo",[3, $request->all()]);
            SetNXLock::release($redisKey);
            return apiReturnFail(["web.withdraw.pix_type_missing",'O tipo PIX está ausente']);
        }

        // 验证PixNum绑定次数
//        if (!empty($PixNum)) {
//            $BindCount = DB::table(TableName::QPRecordDB() . 'RecordBankCardBind')
//                ->where('BankCard', $PixNum)
//                ->lock('WITH(NOLOCK)')
//                ->count();
//            if ($BindCount >= 6) {
//                Util::WriteLog("withdrawInfo",[4, $request->all()]);
//                SetNXLock::release($redisKey);
//                return apiReturnFail(['web.withdraw.cpf_number_used','O número do CPF foi usado várias vezes e não pode ser salvo'], [], 302);
//            }
//        }

        if ($PixType==1) {
            // 验证 cashapp
            if (!empty($PixNum)) {
                // 如果 PixNum 第一个字符不是 "$"，则在前面添加 "$"
                if (substr($PixNum, 0, 1) !== '$') {
                    $PixNum = '$' . $PixNum;
                }
                
                // 构建 cash.app URL
                $cashAppUrl = 'https://cash.app/' . $PixNum;
                
                try {
                    // 使用 stream context 来获取 HTTP 响应头
                    $context = stream_context_create([
                        'http' => [
                            'method' => 'GET',
                            'header' => "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\r\n",
                            'ignore_errors' => true
                        ]
                    ]);
                    
                    $htmlContent = @file_get_contents($cashAppUrl, false, $context);
                    
                    // 检查 HTTP 响应头中的状态码
                    if ($htmlContent === false || (isset($http_response_header) && preg_match('/HTTP\/\d\.\d\s+404/', implode("\n", $http_response_header)))) {
                        Util::WriteLog("withdrawInfo", [5, $request->all(), 'Invalid cashapp: ' . $PixNum]);
                        SetNXLock::release($redisKey);
                        return apiReturnFail(['web.withdraw.invalid_cashapp', 'Invalid CashApp account']);
                    }
                    
                    if ($htmlContent !== false) {
                        // 去除空格换行，转换成一行字符串
                        $htmlContent = preg_replace('/\s+/', '', $htmlContent);
                        Util::WriteLog("withdrawInfo", [5, $request->all(), 'CashApp verification response: ' . $htmlContent]);
                        
                        // 检查响应内容中是否包含 "404 Not Found"
                        if (stripos($htmlContent, '404NotFound') !== false) {
                            Util::WriteLog("withdrawInfo", [5, $request->all(), 'Invalid cashapp: ' . $PixNum]);
                            SetNXLock::release($redisKey);
                            return apiReturnFail(['web.withdraw.invalid_cashapp', 'Invalid CashApp account']);
                        }
                    }
                } catch (\Exception $e) {
                    // 其他异常也记录日志但不阻止流程
                    Util::WriteLog("withdrawInfo", [5, $request->all(), 'CashApp verification error: ' . $e->getMessage()]);
                }
            }
            
            $data = compact('PixType', 'BankUserName',  'PixNum');
            


        } else {
            $data = compact('PixType', 'EmailAddress');
        }

        foreach ($data as $key => &$val) {
            $data[$key] = trim($val);
        }
        unset($val);


        $AccountWithDrawInfo = DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
            ->lock('WITH(NOLOCK)')
            ->where('UserID', $UserID)
            ->first();
        if (!$AccountWithDrawInfo) {
            $data['UserID'] = $UserID;
            $data['Achieves'] = 0;
            $data['HistoryWithDraw'] = 0;
            try {
                DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
                    ->where('UserID', $UserID)
                    ->insert($data);
            } catch (\Exception $e) {
                    Log::error('insert AccountWithDrawInfo failed', ['data' => $data]);
                Util::WriteLog("withdrawInfo",[6, $request->all(),$data]);
            }

        } else {
            DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
                ->where('UserID', $UserID)
                ->update($data);
        }

        // 记录修改时间，限制24小时
        Redis::setex($limitKey, 86400, time());

        SetNXLock::release($redisKey);
        return apiReturnSuc();
    }
    public function withDrawInfoSA(Request $request)
    {

//        return apiReturnFail('params error');

        $UserID = $request->input('UserID');
        $RequestDynamicPass = $request->input('DynamicPass');
        $PixType = $request->input('cbPixType');
        $BankNO = $request->input('bank');
        $AccountsBank = urldecode($request->input('account'));
        $BankUserName = urldecode($request->input('userName'));
        // 原始代码
        $BankUserName = Util::filterNickName($BankUserName);

        // 新增处理：在大写字母前加空格
        $BankUserName = preg_replace('/(?<!^)([A-Z])/', ' $1', $BankUserName);

        $PhoneNumber = $request->input('phone');
        $EmailAddress = $request->input('email');
        $IFSCNumber = $request->input('IFSC');
        $PANNumber = $request->input('PAN');
        $AdhaarNumber = $request->input('adhaar');
        $BranchBank = $request->input('branceBank');
        $PixNum = $request->input('PixNum');
        $redisKey = 'withDrawInfo_withDrawInfo_'.$UserID;
        if (!SetNXLock::getExclusiveLock($redisKey)) {
            Util::WriteLog("withdrawInfo",[1, $request->all()]);
            return apiReturnFail('Tente novamente mais tarde');
        }

        if (!$UserID) {
            Util::WriteLog("withdrawInfo",[2, $request->all()]);
            Log::info('miss UserID', $request->all());
            SetNXLock::release($redisKey);
            return apiReturnFail('params error');
        }
        if (empty($PixType)) {
            Util::WriteLog("withdrawInfo",[3, $request->all()]);
            SetNXLock::release($redisKey);
            return apiReturnFail('O tipo PIX está ausente');
        }

//        Util::validateSouthAmericanPhone('',)

        // 验证PixNum绑定次数
        if (!empty($PixNum)) {
            $BindCount = DB::table(TableName::QPRecordDB() . 'RecordBankCardBind')
                ->where('BankCard', $PixNum)
                ->lock('WITH(NOLOCK)')
                ->count();
            if ($BindCount >= 8) {
                Util::WriteLog("withdrawInfo",[4, $request->all()]);
                SetNXLock::release($redisKey);
                return apiReturnFail(['web.withdraw.cpf_number_used','The CPF number has been used several times and cannot be saved'], [], 302);
            }
        }

//        if(!is_numeric($PixNum)){
//            return apiReturnFail(['web.withdraw.pix_failed','The CPF number has been used several times and cannot be saved'], [], 302);
//        }
        // 验证玩家信息
        $DynamicPass = DB::table(TableName::QPAccountsDB() . 'AccountsInfo')
            ->where('UserID', $UserID)
            ->lock('WITH(NOLOCK)')
            ->value('DynamicPass');
        if ($DynamicPass != $RequestDynamicPass || empty($DynamicPass)) {
            SetNXLock::release($redisKey);
            Util::WriteLog("withdrawInfo",[5, $request->all()]);
            return apiReturnFail('As informações do jogador são inconsistentes');
        }
        $data = compact('PixType', 'BankUserName', 'PhoneNumber', 'EmailAddress', 'PixNum','BankNO', 'AccountsBank', 'IFSCNumber', 'PANNumber', 'AdhaarNumber', 'BranchBank');


        foreach ($data as $key => &$val) {
            $data[$key] = trim($val);
        }
        unset($val);


        $AccountWithDrawInfo = DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
            ->lock('WITH(NOLOCK)')
            ->where('UserID', $UserID)
            ->first();
        if (!$AccountWithDrawInfo) {
            $data['UserID'] = $UserID;
            $data['Achieves'] = 0;
            $data['HistoryWithDraw'] = 0;
            try {
                DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
                    ->where('UserID', $UserID)
                    ->insert($data);
            } catch (\Exception $e) {
                Log::error('insert AccountWithDrawInfo failed', ['data' => $data]);
                Util::WriteLog("withdrawInfo",[6, $request->all(),$data]);
            }

        } else {

            $data = array_filter($data, function ($value) {
                return !is_null($value) && $value !== '';
            });
            DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
                ->where('UserID', $UserID)
                ->update($data);
        }

        // 添加绑定记录
        if (empty($AccountWithDrawInfo->PixNum) || $AccountWithDrawInfo->PixNum != $PixNum) {
            try {
                if(!DB::table(TableName::QPRecordDB() . 'RecordBankCardBind')->where('UserID', $UserID)->exists()&&is_numeric($PixNum)) {
                    DB::table(TableName::QPRecordDB() . 'RecordBankCardBind')
                        ->insert([
                            'UserID'   => $UserID,
                            'BankCard' => $PixNum ?? '',
                            'BindDate' => now()
                        ]);
                    Util::WriteLog('update_pix', [
                        'UserID'   => $UserID,
                        'BankCard' => $PixNum ?? '',
                        'BindDate' => now()
                    ]);
                }
            } catch (\Exception $e) {
                Log::error('insert RecordBankCardBind failed', ['data' => $data]);
                Util::WriteLog("withdrawInfo",[7, $request->all(),$data]);
            }

        }
        SetNXLock::release($redisKey);
        return apiReturnSuc();
    }
    public function kycSimpleEU(Request $request)
    {

//        return apiReturnFail('params error');
        $user = $request->user();
        $UserID=$user->UserID;
        $firstName = Util::filterNickName(urldecode($request->input('firstName')));
        $lastName = Util::filterNickName(urldecode($request->input('lastName')));
        // 原始代码
        $BankUserName = $firstName.'|'.$lastName;


        $PhoneNumber = $request->input('phone');
        $EmailAddress = $request->input('email');


        Util::WriteLog("kyc_eu",$request->all());
        if(isset($EmailAddress)&&!empty($EmailAddress)){
            $validator = Validator::make(
                ['email' => $EmailAddress],
                ['email' => 'required|email']
            );

            if ($validator->fails()) {
                return apiReturnFail(['web.user.email_fail','Wrong email format']);
            }
        }


        if (!$BankUserName || $BankUserName == 'undefined') {
            return apiReturnFail(['web.bank.username_empty', 'The name cannot be empty']);
        }


        $redisKey = 'withDrawInfo_withDrawInfo_' . $UserID;
        if (!SetNXLock::getExclusiveLock($redisKey)) {
            return apiReturnFail(['web.bank.try_again_later', 'Please try again later']);
        }

        if (!$UserID) {
            Log::info('miss UserID', $request->all());
            SetNXLock::release($redisKey);
            return apiReturnFail(['web.bank.missing_userid', 'params error']);
        }


        $data = compact('BankUserName', 'PhoneNumber', 'EmailAddress');


        foreach ($data as $key => &$val) {
            $data[$key] = trim($val);
            if(empty($val))unset($data[$key]);
        }
        unset($val);


        $AccountWithDrawInfo = DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
            ->lock('WITH(NOLOCK)')
            ->where('UserID', $UserID)
            ->first();
        if (!$AccountWithDrawInfo) {
            $data['UserID'] = $UserID;
            $data['Achieves'] = 0;
            $data['HistoryWithDraw'] = 0;
            try {
                DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
                    ->where('UserID', $UserID)
                    ->insert($data);
            } catch (\Exception $e) {
                Log::error('insert AccountWithDrawInfo failed', ['data' => $data]);
            }

        } else {
            DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
                ->where('UserID', $UserID)
                ->update($data);
        }


        SetNXLock::release($redisKey);
        return apiReturnSuc();
    }
    public function withDrawInfoEU(Request $request)
    {

//        return apiReturnFail('params error');
        $user = $request->user();
        $UserID=$user->UserID;
//        $UserID = $request->input('UserID');
//        $RequestDynamicPass = $request->input('DynamicPass');
        $PixType = $request->input('cbPixType');
        $firstName = Util::filterNickName(urldecode($request->input('firstName')));
        $lastName = Util::filterNickName(urldecode($request->input('lastName')));
        // 原始代码
        $BankUserName = $firstName.'|'.$lastName;



        $BankNO = $request->input('account');
        $AccountsBank = $request->input('account');
        $PhoneNumber = $request->input('phone');
        $EmailAddress = $request->input('email');
        $IFSCNumber = $request->input('IFSCNumber');
        $BranchBank = $request->input('bank');//银行编号
        $PixNum = $request->input('account');

        Util::WriteLog("euwithdraw",$request->all());
        if(isset($EmailAddress)&&!empty($EmailAddress)){
            $validator = Validator::make(
                ['email' => $EmailAddress],
                ['email' => 'required|email']
            );

            if ($validator->fails()) {
                return apiReturnFail(['web.user.email_fail','Wrong email format']);
            }
        }
        if (!$AccountsBank || $AccountsBank == 'undefined') {
            return apiReturnFail(['web.bank.account_empty', 'The bank account cannot be empty']);
        }

        if (!(strlen($AccountsBank) == 16 || strlen($AccountsBank) == 18)) {
            return apiReturnFail(['web.bank.account_invalid_length', 'The bank number must have 16 or 18 digits']);
        }

        if (!(strlen($IFSCNumber) == 18 && $IFSCNumber)) {
            return apiReturnFail(['web.bank.clabe_invalid_length', 'The Clabe number must have 18 digits']);
        }

        if (!$BankUserName || $BankUserName == 'undefined') {
            return apiReturnFail(['web.bank.username_empty', 'The name cannot be empty']);
        }

        if (!$BranchBank || $BranchBank == 'undefined') {
            return apiReturnFail(['web.bank.branch_empty', 'The branch code cannot be empty']);
        }

        if (strlen($AccountsBank) == 16) {
            $PixType = 2;
        }

        if (strlen($AccountsBank) == 18) {
            $PixType = 1;
        }

        $redisKey = 'withDrawInfo_withDrawInfo_' . $UserID;
        if (!SetNXLock::getExclusiveLock($redisKey)) {
            return apiReturnFail(['web.bank.try_again_later', 'Please try again later']);
        }

        if (!$UserID) {
            Log::info('miss UserID', $request->all());
            SetNXLock::release($redisKey);
            return apiReturnFail(['web.bank.missing_userid', 'params error']);
        }

        if (empty($PixType)) {
            SetNXLock::release($redisKey);
            return apiReturnFail(['web.bank.pix_type_missing', 'The PIX type is missing']);
        }

// 验证PixNum绑定次数
        if (!empty($PixNum)) {
            $BindCount = DB::table(TableName::QPRecordDB() . 'RecordBankCardBind')
                ->where('BankCard', $PixNum)
                ->lock('WITH(NOLOCK)')
                ->count();
            if ($BindCount >= 3) {
                SetNXLock::release($redisKey);
                return apiReturnFail(['web.bank.cpf_used_multiple_times', 'The CPF number has been used multiple times and cannot be saved'], [], 302);
            }
        }


        // 验证玩家信息
        if (!empty($user->InsurePass)&&!Hash::check($paypass,$user->InsurePass)) {
            return apiReturnFail(['web.user.paypass_fail', 'A senha original está errada, digite-a novamente.'], '', 2);
        }


        if ($PixType < 10 && false) {
            $data = compact('PixType', 'BankUserName', 'PhoneNumber', 'EmailAddress', 'PixNum');
        } else {
            $data = compact('PixType', 'BankUserName','IFSCNumber', 'PhoneNumber', 'EmailAddress','BankNO', 'AccountsBank','BranchBank','PixNum');
            $PixNum = $BankNO;
        }

        foreach ($data as $key => &$val) {
            $data[$key] = trim($val);
        }
        unset($val);


        $AccountWithDrawInfo = DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
            ->lock('WITH(NOLOCK)')
            ->where('UserID', $UserID)
            ->first();
        if (!$AccountWithDrawInfo) {
            $data['UserID'] = $UserID;
            $data['Achieves'] = 0;
            $data['HistoryWithDraw'] = 0;
            try {
                DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
                    ->where('UserID', $UserID)
                    ->insert($data);
            } catch (\Exception $e) {
                Log::error('insert AccountWithDrawInfo failed', ['data' => $data]);
            }

        } else {
            DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
                ->where('UserID', $UserID)
                ->update($data);
        }

        // 添加绑定记录
        if (empty($AccountWithDrawInfo->PixNum) || $AccountWithDrawInfo->PixNum != $PixNum) {
            try {
                DB::table(TableName::QPRecordDB() . 'RecordBankCardBind')
                    ->insert([
                        'UserID' => $UserID,
                        'BankCard' => $PixNum ?: '',
                        'BindDate' => now()
                    ]);
            } catch (\Exception $e) {
                Log::error('insert RecordBankCardBind failed', ['data' => $data]);
            }

        }
        SetNXLock::release($redisKey);
        return apiReturnSuc();
    }
    // 获取提现信息
    public function getWithDrawInfo(Request $request)
    {
//        $UserID = (int)$request->globalUser->UserID;//$request->input('UserID');
        $user = $request->user();
        $UserID=$user->UserID;
//        $paypass = $request->input('paypass');
//        if (!empty($user->InsurePass)&&!Hash::check($paypass,$user->InsurePass)) {
//            return apiReturnFail(['web.user.paypass_fail', 'A senha original está errada, digite-a novamente.'], '', 2);
//        }



        $info = DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
            ->where('UserID', $UserID)
            ->lock('WITH(NOLOCK)')
            ->first();
        if (!$info) {   // 赋值 -- 避免客户端报错
            $info = [
//                'BankNO' => '',
//                'AccountsBank' => '',
                'BankUserName' => '',
//                'PhoneNumber' => '',
//                'IFSCNumber' => '',
                'EmailAddress' => '',
//                'Achieves' => '',
//                'PANNumber' => '',
//                'AdhaarNumber' => '',
//                'BranchBank' => '',
                'PixNum' => '',
                'PixType' => '',
            ];
        }

        $info = json_decode(json_encode($info),true);

        if(env('REGION_24680')=='na-mexico') {
            $info['bank_list'] = config('games.mex_bank_list');
        }else if(env('REGION_24680')=='eu-russian') {
            $info['bank_list'] = config('games.ru_bank_list');
        }

        // 获取绑定手机号
        $phone = DB::table(TableName::QPAccountsDB() . 'AccountPhone')->where('UserID', $UserID)->value('PhoneNum');
        if ($phone) {
            // 简单脱敏处理，例如：5511******88
            $info['bind_phone'] = substr($phone, 0, 4) . '****' . substr($phone, -2);
        } else {
            $info['bind_phone'] = '';
        }

        $AccountsInfoModel = new AccountsInfo();
        $total = $AccountsInfoModel->accountTotalStatistics([$UserID]);
        $totalRecharge= @$total[0]->Recharge ??  0;

        $info['total_recharge'] = intval($totalRecharge);
        $info['withdraw_level'] = env('MIN_RECHARGE',20);
        $hasSuccessWithdraw = DB::table('QPAccountsDB.dbo.OrderWithDraw')
            ->lock('WITH(NOLOCK)')
            ->where('UserID', $UserID)
            ->where('State', 2)
            ->exists();
        $info['has_success_withdraw'] = $hasSuccessWithdraw;

        return apiReturnSuc(compact('info'));
    }
}
