<?php

namespace app\api\controller\v1;

use addons\webman\model\Activity;
use addons\webman\model\ActivityContent;
use addons\webman\model\BankList;
use addons\webman\model\Broadcast;
use addons\webman\model\Channel;
use addons\webman\model\ChannelRechargeSetting;
use addons\webman\model\Currency;
use addons\webman\model\Notice;
use addons\webman\model\PlayerBank;
use addons\webman\model\PlayerDeliveryRecord;
use addons\webman\model\PlayerRechargeRecord;
use addons\webman\model\PlayerWalletTransfer;
use addons\webman\model\PlayerWithdrawRecord;
use app\exception\GameException;
use app\exception\PlayerCheckException;
use Exception;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;
use Respect\Validation\Exceptions\AllOfException;
use Respect\Validation\Validator as v;
use support\Db;
use support\Request;
use support\Response;
use Tinywan\Jwt\JwtToken;

class IndexController
{
    /** 排除验签 */
    protected $noNeedSign = [];

    /**
     * 登出接口
     * @return Response
     * @throws PlayerCheckException|GameException
     */
    public function logout(): Response
    {
        checkPlayer();
        if (JwtToken::clear()) {
            return jsonSuccessResponse('success');
        }

        return jsonFailResponse(trans('logout_failed', [], 'message'));
    }

    /**
     * 添加银行卡
     * @param Request $request
     * @return Response
     * @throws GameException
     * @throws PlayerCheckException
     */
    public function addBankCard(Request $request): Response
    {
        $player = checkPlayer();
        $data = $request->all();
        $validator = v::key('bank_name', v::optional(v::stringType()->length(1, 100)->setName(trans('bank_name', [], 'message'))))
            ->key('account', v::optional(v::stringType()->length(1, 255)->setName(trans('bank_account', [], 'message'))))
            ->key('account_name', v::optional(v::stringType()->length(1, 100)->setName(trans('bank_account_name', [], 'message'))))
            ->key('bank_code', v::optional(v::stringType()->length(1, 100)->setName(trans('bank_code', [], 'message'))))
            ->key('wallet_address', v::optional(v::stringType()->length(1, 255)->setName(trans('wallet_address', [], 'message'))))
            ->key('qr_code', v::optional(v::stringType()->setName(trans('qr_code', [], 'message'))));

        try {
            $validator->assert($data);
        } catch (AllOfException $e) {
            return jsonFailResponse(getValidationMessages($e));
        }
        if (!empty($data['account']) && PlayerBank::query()->where('account', $data['account'])
                ->where('pay_type', $player->channel->pay_type)->exists()) {
            return jsonFailResponse(trans('bank_card_has_bind', [], 'message'));
        }
        $payType = $player->channel->pay_type;

        //USDT判断
        if (!empty($data['wallet_address'])) {
            $payType = 4;
            if (PlayerBank::query()->where('wallet_address', $data['wallet_address'])->where('pay_type', 4)->exists()) {
                return jsonFailResponse(trans('bank_card_has_bind', [], 'message'));
            }
        }
        $bankNum = PlayerBank::query()
            ->where('player_id', $player->id)
            ->where('status', 1)
            ->where('pay_type', $player->channel->pay_type)
            ->count();
        if ($bankNum > 2) {
            return jsonFailResponse(trans('bank_card_max_three', [], 'message'));
        }
        $playerBank = new PlayerBank();
        $playerBank->player_id = $player->id;
        $playerBank->bank_name = $data['bank_name'];
        $playerBank->account = $data['account'];
        $playerBank->account_name = $data['account_name'];
        $playerBank->wallet_address = $data['wallet_address'] ?? '';
        $playerBank->qr_code = $data['qr_code']  ?? '';
        $playerBank->bank_code = $data['bank_code'];
        $playerBank->pay_type = $payType;
        if (!$playerBank->save()) {
            return jsonFailResponse(trans('add_bank_card_fail', [], 'message'));
        }

        return jsonSuccessResponse(trans('add_bank_card_success', [], 'message'));
    }

    /**
     * 修改银行卡
     * @param Request $request
     * @return Response
     * @throws GameException
     * @throws PlayerCheckException
     */
    public function editBankCard(Request $request): Response
    {
        $player = checkPlayer();
        $data = $request->all();
        $validator = v::key('bank_name', v::notEmpty()->stringType()->length(1, 100)->setName(trans('bank_name', [], 'message')))
            ->key('account_name', v::notEmpty()->stringType()->length(1, 100)->setName(trans('bank_account_name', [], 'message')))
            ->key('bank_code', v::notEmpty()->stringType()->length(1, 100)->setName(trans('bank_code', [], 'message')))
            ->key('id', v::notEmpty()->stringType()->length(1, 100)->setName(trans('id', [], 'message')));

        try {
            $validator->assert($data);
        } catch (AllOfException $e) {
            return jsonFailResponse(getValidationMessages($e));
        }
        if (PlayerBank::query()->where('player_id', $player->id)->where('status', 1)->count() > 2) {
            return jsonFailResponse(trans('bank_card_max_three', [], 'message'));
        }
        $playerBank =  PlayerBank::query()->find($data['id']);
        if ($playerBank->player_id != $player->id) {
            return jsonFailResponse(trans('edit_bank_card_fail', [], 'message'));
        }
        $playerBank->bank_name = $data['bank_name'];
        $playerBank->account = $data['account'];
        $playerBank->account_name = $data['account_name'];
        $playerBank->bank_code = $data['bank_code'];
        if (!$playerBank->save()) {
            return jsonFailResponse(trans('edit_bank_card_fail', [], 'message'));
        }
        return jsonSuccessResponse(trans('edit_bank_card_success', [], 'message'));
    }

    /**
     * 银行卡列表
     * @param Request $request
     * @return Response
     * @throws PlayerCheckException|GameException
     */
    public function bankCardList(Request $request): Response
    {
        $player = checkPlayer();
        $data = $request->all();
        $validator = v::key('page', v::intVal()->setName(trans('page', [], 'message')))
            ->key('size', v::intVal()->setName(trans('size', [], 'message')));

        try {
            $validator->assert($data);
        } catch (AllOfException $e) {
            return jsonFailResponse(getValidationMessages($e));
        }

        return jsonSuccessResponse('success', [
            'bank_list' => PlayerBank::query()
                ->where('player_id', $player->id)
                ->where('status', 1)
                ->where('pay_type', $player->channel->pay_type)
                ->whereNull('deleted_at')
                ->select(['id', 'bank_name', 'account', 'account_name'])
                ->forPage($data['page'] ?? 1, $data['size'] ?? 10)
                ->orderBy('created_at', 'desc')
                ->get()
                ->toArray(),
        ]);
    }

    /**
     * 银行卡列表
     * @return Response
     * @throws PlayerCheckException|GameException|\think\Exception
     */
    public function bankList(): Response
    {
        $player = checkPlayer(false);
        return jsonSuccessResponse('success', [
            'bank_list' => BankList::query()
                ->select(['bank_name', 'bank_code'])
                ->where('pay_type', $player->channel->pay_type)
                ->where('type', '!=', 1)
                ->whereNull('deleted_at')
                ->get()
                ->toArray(),
        ]);
    }

    /**
     * 删除银行卡
     * @param Request $request
     * @return Response
     * @throws PlayerCheckException|GameException
     */
    public function deleteBankCard(Request $request): Response
    {
        $player = checkPlayer();
        $data = $request->all();
        $validator = v::key('id', v::intVal()->notEmpty()->setName(trans('bank_card_id', [], 'message')));
        try {
            $validator->assert($data);
        } catch (AllOfException $e) {
            return jsonFailResponse(getValidationMessages($e));
        }

        $bankCard = PlayerBank::withTrashed()->where('player_id', $player->id)->where('id', $data['id'])->first();
        if (!$bankCard) {
            return jsonFailResponse(trans('bank_card_not_found', [], 'message'));
        }
        if ($bankCard->status == 0) {
            return jsonFailResponse(trans('bank_card_disabled', [], 'message'));
        }
        if (!empty($bankCard->deleted_at)) {
            return jsonFailResponse(trans('bank_card_deleted', [], 'message'));
        }
        $bankCard->delete();

        return jsonSuccessResponse(trans('success', [], 'message'));
    }

    /**
     * 上传支付凭证
     * @param Request $request
     * @return Response
     * @throws GameException
     * @throws PlayerCheckException
     */
    public function uploadCertificate(Request $request): Response
    {
        checkPlayer();
        $file = $request->file('certificate');
        $filePath = '';
        if ($file && $file->isValid()) {
            if ($file->getSize() > 3 * 1024 * 1024) {
                return jsonFailResponse(trans('image_upload_size_fail', ['{size}' => '3M'], 'message'));
            }
            $allowedExtensions = ['png', 'jpg', 'jpeg'];
            $extension = $file->getUploadExtension();
            if (!in_array($extension, $allowedExtensions)) {
                return jsonFailResponse(trans('image_upload_fail', [], 'message'));
            }
            $savePath = '/storage/certificate/' . date("Ymd", time()) . "/";
            $newPath = public_path() . $savePath;
            if (!file_exists($newPath)) {
                //检查是否有该文件夹，如果没有就创建，并给予最高权限
                mkdir($newPath, 0755, true);
            }
            $extension = $file->getUploadExtension();
            $filename = time() . '_' . uniqid() . ".{$extension}"; //文件名
            $newPath = $newPath . $filename;
            $file->move($newPath);
            $filePath = env('APP_URL', 'http://127.0.0.1:8787') . $savePath . $filename;
        }
        if (!$filePath) {
            return jsonFailResponse(trans('failed_to_upload_recharge_voucher', [], 'message'));
        }

        return jsonSuccessResponse('success', ['file_path' => $filePath]);
    }

    /**
     * 玩家充值
     * @param Request $request
     * @return Response
     * @throws PlayerCheckException
     * @throws Exception
     */
    public function playerRecharge(Request $request): Response
    {
        $player = checkPlayer();
        $data = $request->all();
        $validator = v::key('id', v::notEmpty()->intVal()->setName(trans('recharge_setting_id', [], 'message')))
            ->key('certificate', v::notEmpty()->url()->notEmpty()->setName(trans('certificate', [], 'message')));

        try {
            $validator->assert($data);
        } catch (AllOfException $e) {
            return jsonFailResponse(getValidationMessages($e));
        }

        $rechargeRecord = PlayerRechargeRecord::where('player_id', $player->id)
            ->where('status', PlayerRechargeRecord::STATUS_WAIT)
            ->where('type', PlayerRechargeRecord::TYPE_REGULAR)
            ->first();
        if (!empty($rechargeRecord)) {
            return jsonFailResponse(trans('has_not_unfinished_recharge', [], 'message'));
        }
        /** @var Channel $channel */
        $channel = Channel::where('department_id', $player->department_id)->first();
        if (empty($channel)) {
            return jsonFailResponse(trans('channel_not_found', [], 'message'));
        }
        if ($channel->recharge_status == 0) {
            return jsonFailResponse(trans('recharge_closed', [], 'message'));
        }
        $lang = locale();
        $lang = Str::replace('_', '-', $lang);
        /** @var ChannelRechargeSetting $channelRechargeSetting */
        $channelRechargeSetting = ChannelRechargeSetting::with(['channel_recharge_method' => function ($query) use ($lang) {
            $query->select(['id', 'account', 'currency'])->with(['methodLang' => function ($query) use ($lang) {
                $query->select(['id', 'bank_name', 'sub_bank', 'owner', 'name', 'method_id', 'lang'])->where('lang', $lang);
            }]);
        }])->whereHas('channel_recharge_method', function ($query) {
            $query->whereNull('deleted_at')->where('status', 1);
        })
            ->where('department_id', $player->department_id)
            ->where('status', 1)
            ->where('id', $data['id'])
            ->whereNull('deleted_at')
            ->first();
        if (empty($channelRechargeSetting)) {
            return jsonFailResponse(trans('channel_recharge_setting_not_found', [], 'message'));
        }
        try {
            $allCoins = bcadd($channelRechargeSetting->coins_num, $channelRechargeSetting->gift_coins, 2);
            // 生成充值订单
            $playerRechargeRecord = new  PlayerRechargeRecord();
            $playerRechargeRecord->player_id = $player->id;
            $playerRechargeRecord->department_id = $player->department_id;
            $playerRechargeRecord->tradeno = createOrderNo();
            $playerRechargeRecord->player_name = $player->name ?? '';
            $playerRechargeRecord->money = $channelRechargeSetting->money;
            $playerRechargeRecord->inmoney = $channelRechargeSetting->money;
            $playerRechargeRecord->setting_id = $channelRechargeSetting->id;
            $playerRechargeRecord->coins = $channelRechargeSetting->coins_num;
            $playerRechargeRecord->gift_coins = $channelRechargeSetting->gift_coins;
            $playerRechargeRecord->currency = $channelRechargeSetting->channel_recharge_method->currency;
            $playerRechargeRecord->type = $channelRechargeSetting->type;
            $playerRechargeRecord->status = PlayerRechargeRecord::STATUS_RECHARGING;
            $playerRechargeRecord->certificate = $data['certificate'] ?? '';
            $playerRechargeRecord->bank_name = $channelRechargeSetting->channel_recharge_method->methodLang[0]['bank_name'] ?? '';
            $playerRechargeRecord->sub_bank = $channelRechargeSetting->channel_recharge_method->methodLang[0]['sub_bank'] ?? '';
            $playerRechargeRecord->owner = $channelRechargeSetting->channel_recharge_method->methodLang[0]['owner'] ?? '';
            $playerRechargeRecord->account = $channelRechargeSetting->channel_recharge_method->account;
            $playerRechargeRecord->chip_amount = bcmul($allCoins, $channelRechargeSetting->chip_multiple, 2);
            $playerRechargeRecord->save();
        } catch (Exception $e) {
            return jsonFailResponse($e->getMessage());
        }

        sendSocketMessage('private-admin_group-channel-' . request()->department_id, [
            'msg_type' => 'player_examine_recharge_order',
            'id' => $rechargeRecord->id,
            'player_id' => $player->id,
            'player_name' => $player->name,
            'player_phone' => $player->phone,
            'money' => $playerRechargeRecord->money,
            'status' => $playerRechargeRecord->status,
            'tradeno' => $playerRechargeRecord->tradeno,
        ]);

        return jsonSuccessResponse('success', [
            'tradeno' => $playerRechargeRecord->tradeno,
            'order_id' => $playerRechargeRecord->id,
            'money' => $playerRechargeRecord->money,
            'coins' => $allCoins,
            'currency' => $playerRechargeRecord->currency,
            'status' => $playerRechargeRecord->status,
            'created_at' => strtotime($playerRechargeRecord->created_at),
            'recharge_setting' => $channelRechargeSetting
        ]);
    }

    /**
     * 提现记录
     * @param Request $request
     * @return Response
     * @throws PlayerCheckException|GameException
     */
    public function cashOutList(Request $request): Response
    {
        $player = checkPlayer();
        $data = $request->all();
        $validator = v::key('page', v::intVal()->setName(trans('page', [], 'message')))
            ->key('size', v::intVal()->setName(trans('size', [], 'message')));

        try {
            $validator->assert($data);
        } catch (AllOfException $e) {
            return jsonFailResponse(getValidationMessages($e));
        }
        $size = $data['size'] ?? 10;
        $totalRecords = PlayerWithdrawRecord::query()
            ->where('player_id', $player->id)
            ->count();

        return jsonSuccessResponse('success', [
            'list' => PlayerWithdrawRecord::where('player_id', $player->id)
                ->select(['id', 'coins', 'after_coins', 'created_at', 'status'])
                ->forPage($data['page'] ?? 1, $data['size'] ?? 10)
                ->orderBy('created_at', 'desc')
                ->get()
                ->toArray(),
            'total_page' => ceil($totalRecords / $size)
        ]);
    }

    /**
     * 玩家提现
     * @param Request $request
     * @return Response
     * @throws PlayerCheckException
     * @throws Exception
     */
    public function playerWithdrawal(Request $request): Response
    {
        $player = checkPlayer();
        $data = $request->all();
        $validator = v::key('amount', v::intVal()->notEmpty()->min(100)->setName(trans('withdrawal_amount', [], 'message')))
            ->key('bank_id', v::intVal()->setName(trans('withdrawal_bank', [], 'message')));

        try {
            $validator->assert($data);
        } catch (AllOfException $e) {
            return jsonFailResponse(getValidationMessages($e));
        }
        /** @var Channel $channel */
        $channel = Channel::where('department_id', $player->department_id)->first();
        if ($player->status_withdraw != 1) {
            return jsonFailResponse(trans('player_withdraw_closed', [], 'message'));
        }
        if ($player->wallet->money < $data['amount']) {
            return jsonFailResponse(trans('insufficient_balance', [], 'message'));
        }
        if ($channel->withdraw_status == 0) {
            return jsonFailResponse(trans('self_withdraw_closed', [], 'message'));
        }
        if (empty($data['bank_id'])) {
            return jsonFailResponse(trans('please_select_player_bank', [], 'message'));
        }
        /** @var Currency $currency */
        $currency = Currency::where('identifying', $channel->currency)->where('status', 1)->whereNull('deleted_at')->first();
        if (empty($currency)) {
            return jsonFailResponse(trans('currency_no_setting', [], 'message'));
        }
        /** @var PlayerBank $playerBank */
        $playerBank = PlayerBank::where('id', $data['bank_id'])->where('player_id', $player->id)->where('status', 1)->whereNull('deleted_at')->first();
        if (empty($playerBank)) {
            return jsonFailResponse(trans('player_bank_not_found', [], 'message'));
        }
        if ($player->must_chip_amount > $player->chip_amount) {
            return jsonFailResponse(trans('must_chip_amount_incomplete', [], 'message'));
        }
        DB::beginTransaction();
        try {
            $money = bcdiv($data['amount'], $currency->ratio, 2);
            // 生成订单
            $playerWithdrawRecord = new PlayerWithdrawRecord();
            $beforeGameAmount = $player->wallet->money;
            // 玩家钱包扣减
            $player->wallet->money = bcsub($player->wallet->money, $data['amount'], 2);
            $playerWithdrawRecord->player_id = $player->id;
            $playerWithdrawRecord->department_id = $player->department_id;
            $playerWithdrawRecord->tradeno = createOrderNo();
            $playerWithdrawRecord->player_name = $player->name ?? '';
            $playerWithdrawRecord->player_phone = $player->phone ?? '';
            $playerWithdrawRecord->money = $money;
            $playerWithdrawRecord->coins = $data['amount'];
            $playerWithdrawRecord->after_coins = $player->wallet->money;
            $playerWithdrawRecord->fee = 0;
            $playerWithdrawRecord->inmoney = bcsub($playerWithdrawRecord->money, $playerWithdrawRecord->fee, 2); // 实际提现金额
            $playerWithdrawRecord->currency = $channel->currency;
            $playerWithdrawRecord->bank_name = $playerBank->bank_name;
            $playerWithdrawRecord->account = $playerBank->account;
            $playerWithdrawRecord->account_name = $playerBank->account_name;
            $playerWithdrawRecord->type = PlayerWithdrawRecord::TYPE_SELF;
            $playerWithdrawRecord->status = PlayerWithdrawRecord::STATUS_WAIT;
            $playerWithdrawRecord->save();

            // 更新玩家统计
            $player->player_extend->withdraw_amount = bcadd($player->player_extend->withdraw_amount, $playerWithdrawRecord->coins, 2);
            $player->push();
            //寫入金流明細
            $playerDeliveryRecord = new PlayerDeliveryRecord;
            $playerDeliveryRecord->player_id = $playerWithdrawRecord->player_id;
            $playerDeliveryRecord->department_id = $playerWithdrawRecord->department_id;
            $playerDeliveryRecord->target = $playerWithdrawRecord->getTable();
            $playerDeliveryRecord->target_id = $playerWithdrawRecord->id;
            $playerDeliveryRecord->type = PlayerDeliveryRecord::TYPE_WITHDRAWAL;
            $playerDeliveryRecord->source = 'channel_withdrawal';
            $playerDeliveryRecord->amount = $playerWithdrawRecord->coins;
            $playerDeliveryRecord->amount_before = $beforeGameAmount;
            $playerDeliveryRecord->amount_after = $player->wallet->money;
            $playerDeliveryRecord->tradeno = $playerWithdrawRecord->tradeno ?? '';
            $playerDeliveryRecord->remark = $playerWithdrawRecord->remark ?? '';
            $playerDeliveryRecord->save();
            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            return jsonFailResponse(trans('system_error', [], 'message') . $e->getMessage());
        }

        $notice = new Notice();
        $notice->department_id = $playerWithdrawRecord->department_id;
        $notice->player_id = $playerWithdrawRecord->player_id;
        $notice->source_id = $playerWithdrawRecord->id;
        $notice->type = Notice::TYPE_EXAMINE_WITHDRAW;
        $notice->receiver = Notice::RECEIVER_DEPARTMENT;
        $notice->is_private = 0;
        $notice->title = '渠道提现待审核';
        $notice->content = '提现订单待审核,玩家' . (empty($playerWithdrawRecord->player_name) ? $playerWithdrawRecord->player_name : $playerWithdrawRecord->player_phone) . ', 提现游戏点: ' . $playerWithdrawRecord->point . ' 提现金额: ' . $playerWithdrawRecord->money;
        $notice->save();

        if ($playerWithdrawRecord->status == PlayerWithdrawRecord::STATUS_FAIL) {
            return jsonFailResponse(trans('withdraw_fail', [], 'message'));
        }
        sendSocketMessage('private-admin_group-channel-' . $channel->department_id, [
            'msg_type' => 'player_create_withdraw_order',
            'id' => $playerWithdrawRecord->id,
            'player_id' => $player->id,
            'player_name' => $player->name,
            'player_phone' => $player->phone,
            'money' => $playerWithdrawRecord->money,
            'status' => $playerWithdrawRecord->status,
            'tradeno' => $playerWithdrawRecord->tradeno,
        ]);
        return jsonSuccessResponse('success', [
            'tradeno' => $playerWithdrawRecord->tradeno,
            'order_id' => $playerWithdrawRecord->id,
            'money' => $playerWithdrawRecord->money,
            'currency' => $playerWithdrawRecord->currency,
            'status' => $playerWithdrawRecord->status,
        ]);
    }

    /**
     * 首页活动
     * @return Response
     * @throws PlayerCheckException|GameException
     */
    public function homeActivity(): Response
    {
        $player = checkPlayer();
        $list = Activity::query()
            ->where('department_id', $player->department_id)
            ->where('status', 1)
            ->limit(3)
            ->orderBy('sort', 'desc')
            ->get();

        $lang = locale();
        $lang = Str::replace('_', '-', $lang);
        $activityList = [];
        /** @var Activity $activity */
        foreach ($list as $activity) {
            /** @var ActivityContent $activityContent */
            $activityContent = $activity->activity_content->where('lang', $lang)->first();
            if ($activity->type == Activity::TYPE_CUSTOM) {
                if (strtotime($activity->start_time) > time() || strtotime($activity->end_time) < time()) {
                    continue;
                }
            }
            if ($activity->type == Activity::TYPE_CYCLE) {
                if ($activity->cycle_type == 'Week' && $activity->cycle_data != Carbon::now()->dayOfWeek) {
                    continue;
                }
                if ($activity->cycle_type == 'Month' && $activity->cycle_data != Carbon::now()->day) {
                    continue;
                }
            }
            $activityList[] = [
                'id' => $activity->id,
                'start_time' => $activity->start_time,
                'end_time' => $activity->end_time,
                'name' => $activityContent->name ?? '',
                'lang' => $activityContent->lang,
                'picture' => $activityContent->picture ?? '',
                'recharge_id' => $activity->recharge_id,
                'method_id' => $activity->channelRechargeSetting->method_id,
            ];
        }

        return jsonSuccessResponse('success', [
            'list' => $activityList,
        ]);
    }

    /**
     * cash in记录
     * @param Request $request
     * @return Response
     * @throws PlayerCheckException|GameException
     */
    public function cashInList(Request $request): Response
    {
        $player = checkPlayer();
        $data = $request->all();
        $validator = v::key('page', v::intVal()->setName(trans('page', [], 'message')))
            ->key('size', v::intVal()->setName(trans('size', [], 'message')));

        try {
            $validator->assert($data);
        } catch (AllOfException $e) {
            return jsonFailResponse(getValidationMessages($e));
        }
        $size = $data['size'] ?? 10;
        $totalRecords = PlayerRechargeRecord::query()
            ->where('player_id', $player->id)
            ->count();
        $list = PlayerRechargeRecord::leftJoin('player_delivery_record as pdr',function ($join){
            $join->on( 'pdr.target_id', '=', 'player_recharge_record.id')
                ->where('pdr.type', '=', PlayerDeliveryRecord::TYPE_RECHARGE);
            })->where('player_recharge_record.player_id', $player->id)
            ->select(['player_recharge_record.id', 'player_recharge_record.status', 'player_recharge_record.coins', 'pdr.amount_after', 'player_recharge_record.created_at'])
            ->forPage($data['page'] ?? 1, $data['size'] ?? 10)
            ->orderBy('player_recharge_record.created_at', 'desc')
            ->get()
            ->toArray();
        foreach ($list as &$item) {
            $item['created_at'] = Carbon::parse($item['created_at'])->format('Y/m/d H:i');
            $item['amount_after'] = round($item['amount_after'], 2);
        }
        return jsonSuccessResponse('success', [
            'list' => $list,
            'total_page' => ceil($totalRecords / $size)
        ]);
    }

    /**
     * 消息列表
     * @param Request $request
     * @return Response
     * @throws PlayerCheckException|GameException
     */
    public function noticeList(Request $request): Response
    {
        $player = checkPlayer();
        $data = $request->all();
        $validator = v::key('page', v::intVal()->setName(trans('page', [], 'message')))
            ->key('size', v::intVal()->setName(trans('size', [], 'message')));

        try {
            $validator->assert($data);
        } catch (AllOfException $e) {
            return jsonFailResponse(getValidationMessages($e));
        }
        $noticeList = Notice::query()
            ->leftJoin('player_withdraw_record', 'player_withdraw_record.id', '=', 'notice.source_id')
            ->select(['notice.id', 'notice.player_id', 'notice.title', 'notice.type', 'notice.content', 'notice.created_at', 'player_withdraw_record.status', 'player_withdraw_record.money'])
            ->where('notice.player_id', $player->id)
            ->where('notice.receiver', Notice::RECEIVER_PLAYER)
            ->where('notice.is_private', 1)
            ->whereNull('notice.deleted_at')
            ->forPage($data['page'], $data['size'])
            ->orderBy('notice.status', 'asc')
            ->orderBy('notice.id', 'desc')
            ->get();
        foreach ($noticeList as &$item) {
            $item['title'] = trans('title.' . $item->type.'.'.$item->status,
                ['{point}' => $item->money],
                'notice');
            $item['content'] = trans('content.' . $item->type.'.'.$item->status,
                ['{point}' => $item->money],
                'notice');
        }
        // 更新为已读状态
        Notice::where('status', 0)
            ->where('receiver', Notice::RECEIVER_PLAYER)
            ->where('is_private', 1)
            ->where('player_id', $player->id)
            ->whereNull('deleted_at')
            ->update([
                'status' => 1
            ]);

        return jsonSuccessResponse('success', [
            'list' => $noticeList
        ]);
    }

    /**
     * 渠道信息
     * @return Response
     * @throws PlayerCheckException|GameException
     */
    public function channelInfo(): Response
    {
        $player = checkPlayer();
        return jsonSuccessResponse('success', [
            'channel_info' => Channel::query()
                ->where('department_id', $player->department_id)
                ->first(),
        ]);
    }

    /**
     * 提现记录
     * @param Request $request
     * @return Response
     * @throws PlayerCheckException|GameException
     */
    public function withdrawList(Request $request): Response
    {
        checkPlayer();
        $date = date('Y-m-d');
        $list = PlayerWithdrawRecord::with('player:id,uuid,phone')
            ->where('status', 2)
            ->whereDate('finish_time', $date)
            ->select(['money', 'player_id', 'updated_at'])
            ->orderBy('finish_time', 'desc')
            ->get()
            ->toArray();
        foreach ($list as &$item) {
            $PlayerWalletTransfer = PlayerWalletTransfer::query()->where('player_id', $item['player_id'])
                ->where('type', PlayerWalletTransfer::TYPE_IN)
                ->where('created_at', '<=', $item['updated_at'])
                ->orderBy('id', 'desc')
                ->first();
            $item['game'] = $PlayerWalletTransfer->gamePlatform->title;
        }
        unset($item);
        $copyList = [];
        $broadcast = Broadcast::query()
            ->select('title','num','phone','updated_at')
            ->where('status', 1)
            ->where('type', 1)
            ->wheredate('date', $date)
            ->get()
            ->toArray();
        foreach ($broadcast as $item) {
            $copyList[] = [
                'money' => $item['num'],
                'player_id' => 0,
                'updated_at' => $item['updated_at'],
                'player' => [
                    'id' => 0,
                    'uuid' => 0,
                    'phone' => $item['phone'],
                ],
                'game' => $item['title']
            ];
        }
        $data = array_merge($list, $copyList);
        $key = array_column($data,'updated_at');
        array_multisort($key, SORT_DESC, $data);
        return jsonSuccessResponse('success', [
            'list' => $data,
        ]);
    }
}
