<?php

namespace app\external;

use addons\webman\model\Broadcast;
use addons\webman\model\Notice;
use addons\webman\model\PlayerGamePlatform;
use addons\webman\model\PlayerRechargeRecord;
use addons\webman\model\Player;
use addons\webman\model\PlayerDeliveryRecord;
use addons\webman\model\PlayerWithdrawRecord;
use app\service\game\MeGa888ServiceInterface;
use app\service\OnePayServices;
use app\service\SePayServices;
use app\service\SklPayServices;
use Respect\Validation\Exceptions\AllOfException;
use Respect\Validation\Validator as v;
use support\Db;
use support\Request;
use support\Log;
use support\Response;
use Webman\Push\PushException;
use Webman\RedisQueue\Redis;

class ExternalApiController
{
    /** 排除  */
    protected $noNeedSign = [];

    /**
     * 网页注册
     * @return Response
     */
    public function login(): Response
    {
        return view('login/index');
    }

    /**
     * app下载
     * @return Response
     */
    public function download(): Response
    {
        return view('login/download');
    }

    /**
     * SKL支付回调
     * @param Request $request
     * @return string
     * @throws PushException
     */
    public function sklRechargeNotify(Request $request): string
    {
        $data = $request->all();
        if ($data['status'] && $data['invoice_no']) {
            /** @var PlayerRechargeRecord $playerRechargeRecord */
            $playerRechargeRecord = PlayerRechargeRecord::query()->where('tradeno', $data['invoice_no'])->where('status', 0)->first();
            if(empty($playerRechargeRecord) || $playerRechargeRecord->money != $data['amount']){
                return 'FAIL';
            }
            if ($data['status'] == 'SUCCESS') {
                if ($playerRechargeRecord->gift_coins > 0) {
                    $firstRecharge = PlayerRechargeRecord::query()
                        ->where('player_id', $playerRechargeRecord->player_id)
                        ->where('status', 2)
                        ->where('setting_id', $playerRechargeRecord->setting_id)
                        ->first();
                    if ($firstRecharge) {
                        $playerRechargeRecord->gift_coins = 0;
                    }
                }
                $addMoney = bcadd($playerRechargeRecord->coins, $playerRechargeRecord->gift_coins, 2);
                DB::beginTransaction();
                try {
                    /** @var Player $player */
                    $player = Player::query()->find($playerRechargeRecord->player_id);
                    $playerRechargeRecord->status = PlayerRechargeRecord::STATUS_RECHARGED_SUCCESS;
                    $playerRechargeRecord->finish_time = date("Y-m-d H:i:s");
                    $playerRechargeRecord->notify_result = json_encode($data);
                    $playerRechargeRecord->save();
                    $beforeGameAmount = $player->wallet->money;
                    // 更新钱包
                    $player->wallet->money = bcadd($player->wallet->money, $addMoney, 2);
                    $player->player_extend->recharge_amount = bcadd($player->player_extend->recharge_amount, $addMoney, 2);
                    $player->push();
                    //寫入金流明細
                    $playerDeliveryRecord = new PlayerDeliveryRecord;
                    $playerDeliveryRecord->player_id = $player->id;
                    $playerDeliveryRecord->department_id = $player->department_id;
                    $playerDeliveryRecord->target = $playerRechargeRecord->getTable();
                    $playerDeliveryRecord->target_id = $playerRechargeRecord->id;
                    $playerDeliveryRecord->type = PlayerDeliveryRecord::TYPE_RECHARGE;
                    $playerDeliveryRecord->source = 'self_recharge';
                    $playerDeliveryRecord->amount = $addMoney;
                    $playerDeliveryRecord->amount_before = $beforeGameAmount;
                    $playerDeliveryRecord->amount_after = $player->wallet->money;
                    $playerDeliveryRecord->tradeno = '';
                    $playerDeliveryRecord->remark = '';
                    $playerDeliveryRecord->save();
                    DB::commit();
                    sendSocketMessage('private-recharge_withdrawal', [
                        'msg_type' => 'recharge',
                        'player_id' => $player->id,
                        'amount' => $player->wallet->money,
                    ]);
                } catch (\Exception $e) {
                    DB::rollBack();
                    Log::info('sklRecharge', (array)$data);
                    return json_encode(['status' => 'RECEIVED']);
                }
                return json_encode(['status' => 'RECEIVED']);
            } else {
                $playerRechargeRecord->status = PlayerRechargeRecord::STATUS_RECHARGED_FAIL;
                $playerRechargeRecord->cancel_time = date('Y-m-d H:i:s');
                $playerRechargeRecord->notify_result = json_encode($data);
                $playerRechargeRecord->save();
                return json_encode(['status' => 'RECEIVED']);
            }
        } else {
            return json_encode(['status' => 'RECEIVED']);
        }
    }

    /**
     * SKL代付回调
     * @param Request $request
     * @return string
     */
    public function sklWithdrawalNotify(Request $request): string
    {
        $data = $request->all();
        if ($data['status'] && $data['invoice_no']) {
            //查询订单是否存在
            /** @var PlayerWithdrawRecord $playerWithdrawRecord */
            $playerWithdrawRecord = PlayerWithdrawRecord::query()->where('tradeno', $data['invoice_no'])->where('status', 1)->first();
            if(empty($playerWithdrawRecord) || $playerWithdrawRecord->money != $data['amount']){
                return 'FAIL';
            }
            if ($data['status'] == 'SUCCESS') {
                $playerWithdrawRecord->status = PlayerWithdrawRecord::STATUS_SUCCESS;
                $playerWithdrawRecord->finish_time = date('Y-m-d H:i:s');
                $playerWithdrawRecord->notify_result = json_encode($data);
                $playerWithdrawRecord->talk_tradeno = $data['transferOut_id'];
                $playerWithdrawRecord->save();
                $broadcast = Broadcast::query()
                    ->where('type', 2)
                    ->where('status', 1)
                    ->where('min_money', '<=', $data['amount'])
                    ->first();
                if (isset($broadcast)){
                    $queue = 'broadcast_tasks';
                    $broadcast_data = [
                        'user_id' => substr($playerWithdrawRecord->player->phone, 2),
                        'money' => $data['amount']
                    ];
                    for ($i = 0; $i < $broadcast->copy_num; $i++) {
                        Redis::send($queue, $broadcast_data);
                    }
                }
                $notice = new Notice();
                $notice->department_id = $playerWithdrawRecord->player->department_id;
                $notice->player_id = $playerWithdrawRecord->player_id;
                $notice->source_id = $playerWithdrawRecord->id;
                $notice->type = Notice::TYPE_WITHDRAW;
                $notice->receiver = Notice::RECEIVER_PLAYER;
                $notice->is_private = 1;
                $notice->title = '下分成功';
                $notice->content = '本次申请已成功处理，下分 ' . $playerWithdrawRecord->money . ' ，请查收。 ';
                $notice->save();
                return json_encode(['status' => 'RECEIVED']);
            } else {
                DB::beginTransaction();
                try {
                    /** @var Player $player */
                    $player = Player::query()->find($playerWithdrawRecord->player_id);
                    $playerWithdrawRecord->status = PlayerWithdrawRecord::STATUS_FAIL;
                    $playerWithdrawRecord->cancel_time = date('Y-m-d H:i:s');
                    $playerWithdrawRecord->notify_result = json_encode($data);
                    $playerWithdrawRecord->talk_tradeno = $data['transferOut_id'];
                    $playerWithdrawRecord->save();
                    $beforeGameAmount = $player->wallet->money;
                    // 更新钱包
                    $player->wallet->money = bcadd($player->wallet->money, $playerWithdrawRecord->coins, 2);
                    $player->push();
                    //寫入金流明細
                    $playerDeliveryRecord = new PlayerDeliveryRecord;
                    $playerDeliveryRecord->player_id = $player->id;
                    $playerDeliveryRecord->department_id = $player->department_id;
                    $playerDeliveryRecord->target = $playerWithdrawRecord->getTable();
                    $playerDeliveryRecord->target_id = $playerWithdrawRecord->id;
                    $playerDeliveryRecord->type = PlayerDeliveryRecord::TYPE_WITHDRAWAL_BACK;
                    $playerDeliveryRecord->source = 'channel_withdrawal';
                    $playerDeliveryRecord->amount = $playerWithdrawRecord->coins;
                    $playerDeliveryRecord->amount_before = $beforeGameAmount;
                    $playerDeliveryRecord->amount_after = $player->wallet->money;
                    $playerDeliveryRecord->tradeno = '';
                    $playerDeliveryRecord->remark = '提现失败返还金额';
                    $playerDeliveryRecord->save();
                    $notice = new Notice();
                    $notice->department_id = $player->department_id;
                    $notice->player_id = $player->id;
                    $notice->source_id = $playerWithdrawRecord->id;
                    $notice->type = Notice::TYPE_WITHDRAW;
                    $notice->receiver = Notice::RECEIVER_PLAYER;
                    $notice->is_private = 1;
                    $notice->title = '下分失败';
                    $notice->content = '本次申请下分 ' . $playerWithdrawRecord->money . ' 已退回，请查收。 ';
                    $notice->save();
                    DB::commit();
                    sendSocketMessage('private-recharge_withdrawal', [
                        'msg_type' => 'withdrawal',
                        'player_id' => $player->id,
                        'amount' => $player->wallet->money,
                    ]);
                } catch (\Exception $e) {
                    DB::rollBack();
                    Log::info('sklWithdrawal', (array)$data);
                    return json_encode(['status' => 'RECEIVED']);
                }
                return json_encode(['status' => 'RECEIVED']);
            }
        } else {
            return json_encode(['status' => 'RECEIVED']);
        }
    }

    /**
     * SKL订单查询
     * @param Request $request
     * @return Response
     */
    public function sklQuery(Request $request): Response
    {
        $validator = v::key('transactionId', v::stringType()->notEmpty()->setName(trans('certificate', [], 'message')));
        $data = $request->get();
        try {
            $validator->assert($data);
        } catch (AllOfException $e) {
            return jsonFailResponse(getValidationMessages($e));
        }
        $params = [
            'orderNo' => $data['transactionId'],
        ];
        $res = (new SklPayServices())->query($params);
        if ($res['status'] == 'SUCCESS') {
            return view('skl/detail_success');
        } elseif ($res['status'] == 'FAILED') {
            return view('skl/detail_fail');
        } elseif ($res['status'] == 'PENDING_QR') {
            return view('skl/detail_paying');
        } elseif ($res['status'] == 'VERIFIED') {
            return view('skl/detail_paying');
        } else {
            return view('sepay/detail_fail');
        }
    }

}
