<?php

namespace app\service\game;

use addons\webman\model\GamePlatform;
use addons\webman\model\Player;
use addons\webman\model\PlayerGamePlatform;
use addons\webman\model\PlayerWalletTransfer;
use app\exception\GameException;
use Exception;
use support\Response;

class Kiss918ServiceInterface extends GameServiceFactory implements GameServiceInterface
{
    public $method = 'POST';
    private $apiDomain;
    private $domain;
    private $auth;
    private $appSecret;
    public $loginId;
    public $password;

    public $gameType = [
        '2' => 'Casino',
        '5' => 'Fishing',
        '8' => 'Bingo',
        '1' => 'Slot',
    ];

    public $localGameType = [
        '2' => '2',//赌场
        '5' => '4',//捕鱼
        '8' => '2',//宾果
        '1' => '1',//斯洛
    ];

    public $failCode = [
        'S200' => '重復請求',
        'F0001' => '無效的簽名',
        'F0002' => '無效的SN',
        'F0003' => '無效的參數',
        'F0004' => '無效的貨幣',
        'F0005' => '玩家已存在',
        'F0006' => '玩家不存在',
        'F0007' => '會員不存在',
        'F0008' => '執行失敗',
        'F0009' => '無效的方法',
        'F0010' => '無效的用戶狀態',
        'F0011' => '玩家狀態無需更新',
        'F0012' => '超出數據範圍',
        'F0013' => '無匹配數據',
        'F0014' => '登入位置被禁止',
        'F0015' => '分數不足夠',
        'F0016' => '不支持禮碼',
        'F0017' => '交易流水號不得重複',
        'F0018' => '系統繁忙',
        'F0019' => '日期時間各式錯誤',
        'F0020' => '超出時間限制範圍（開始時間與結束時間之間不能大於120分鐘）',
        'F0021' => '執行取消',
        'M0001' => '系統維護',
        'M0002' => '系統錯誤',
    ];
    private $admin_user;

    /**
     * @param Player|null $player
     * @param $type
     * @throws Exception
     */
    public function __construct($type, Player $player = null)
    {
        $config = config('game_platform.' . $type);
        $this->auth = $config['auth'];
        $this->admin_user = $config['admin_user'];
        $this->apiDomain = $config['api_domain'];
        $this->recordApi = $config['record_api'];
        $this->domain = $config['domain'];
        $this->appSecret = $config['app_secret'];
        $this->platform = GamePlatform::query()->where('name', $type)->first();
        if (!empty($player)) {
            $this->player = $player;
            $this->getLoginId();
        }
    }

    public function createSign($params): string
    {
        $str = implode('', $params);
        return strtoupper(md5(strtolower($str)));
    }

    /**
     * 更新游戏列表
     * @return false
     */
    public function getSimpleGameList(): bool
    {
        return false;
    }

    /**
     * 获取玩家ID
     * @throws Exception
     */
    protected function getLoginId()
    {
        /** @var PlayerGamePlatform $playerGamePlatform */
        $playerGamePlatform = PlayerGamePlatform::query()->where('platform_id', $this->platform->id)->where('player_id',$this->player->id)->first();
        if (!empty($playerGamePlatform)) {
            $this->password = $playerGamePlatform->player_password;
            return $this->loginId = $playerGamePlatform->player_code;
        }
        return $this->createPlayer([
            'uuid' => $this->player->uuid,
            'name' => $this->player->name,
        ]);
    }

    /**
     * 创建玩家
     * @param array $data
     * @return array|mixed|Response
     * @throws GameException|Exception
     */
    public function createPlayer(array $data = [])
    {
        $time = round(microtime(true)*1000);
        $randomParams = [
            'action' => 'RandomUserName',
            'userName' => $this->admin_user,
            'time' => $time,
            'authcode' => $this->auth,
        ];
        $signature = $this->createSign([$this->auth, $randomParams['userName'], $time ,$this->appSecret]);
        $randomParams['sign'] = $signature;
        $randomUser = dogGetCurl($this->apiDomain.'ashx/account/account.ashx', $randomParams);;
        if(!$randomUser['success'] || empty($randomUser['account'])){
            throw new GameException($randomUser['msg'], 0);
        }
        $password = uniqid();
        $params = [
            'action' => 'addUser',
            'agent' => $this->admin_user,
            'PassWd' => $password,
            'pwdtype' => 1,
            'userName' => $randomUser['account'],
            'Name' => $data['name'],
            'Tel' => $this->player->phone ?? '',
            'Memo' => $data['name'],
            'UserType' => 1,
            'time' => $time,
            'authcode' => $this->auth,
        ];
        $signature = $this->createSign([$this->auth, $params['userName'], $time ,$this->appSecret]);
        $params['sign'] = $signature;
        $result = dogGetCurl($this->apiDomain.'ashx/account/account.ashx', $params);;
        if ($result['code'] == 0 && $result['success']) {
            $playerGamePlatform = new PlayerGamePlatform();
            $playerGamePlatform->player_id = $this->player->id;
            $playerGamePlatform->platform_id = $this->platform->id;
            $playerGamePlatform->player_name = $data['name'];
            $playerGamePlatform->player_code = $randomUser['account'];
            $playerGamePlatform->player_password = $password;
            $playerGamePlatform->save();
            $this->loginId = $playerGamePlatform->player_code;
            $this->password = $playerGamePlatform->player_password;
            return $result;
        }else{
            throw new GameException($result['msg'], 0);
        }
    }

    /**
     * 获取玩家
     * @return array|mixed|Response
     * @throws Exception
     */
    public function getPlayer()
    {
        $time = round(microtime(true)*1000);
        $params = [
            'action' => 'getUserInfo',
            'userName' => $this->loginId,
            'time' => $time,
            'authcode' => $this->auth,
        ];
        $signature = $this->createSign([$this->auth, $this->loginId, $time ,$this->appSecret]);
        $params['sign'] = $signature;
        $result = dogGetCurl($this->apiDomain.'ashx/account/account.ashx', $params);
        if($result['success']){
            return $result;
        }else{
            throw new GameException('Kiss 918 System Error,Please contact the administrator', 0);
        }
    }

    /**
     * 玩家进入游戏
     * @param array $data
     * @return array
     */
    public function login(array $data = []): array
    {
        return ['url' => 'https://yop1.918kiss.com/', 'account' => $this->loginId, 'password' => $this->password];
    }

    /**
     * 获取玩家游戏平台余额
     * @return string|null
     * @throws Exception
     */
    public function getBalance(): string
    {
        $playerInfo = $this->getPlayer();
        return $playerInfo['MoneyNum'];
    }

    /**
     * 玩家钱包转入游戏平台
     * @return array|mixed|null
     * @throws GameException|\think\Exception
     */
    public function balanceTransferOut()
    {
        if($this->player->wallet->money <= 0){
            return true;
        }
        return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_OUT, $this->player->wallet->money);
    }

    /**
     * 游戏平台转入玩家钱包
     * @return array|mixed|null
     * @throws Exception
     */
    public function balanceTransferIn()
    {
        $balance = $this->getBalance();
        if($balance == 0){
            // 记录玩家钱包转出转入记录
            $this->createWalletTransfer(PlayerWalletTransfer::TYPE_IN, 0, 0);
            return true;
        }
        return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_IN, -$balance);
    }

    /**
     *  轉帳進出額度
     * @param $type
     * @param float $amount
     * @param float $reward
     * @return array|mixed|null
     * @throws GameException|\think\Exception
     */
    protected function setBalanceTransfer($type, float $amount = 0, float $reward = 0)
    {
        $time = round(microtime(true)*1000);
        $params = [
            'action' => 'setServerScore',
            'orderid' => date('YmdHis').uniqid(),
            'scoreNum' => $amount,
            'userName' => $this->loginId,
            'ActionUser' => $this->loginId,
            'ActionIp' => request()->getRealIp(),
            'time' => $time,
            'authcode' => $this->auth,
        ];
        $signature = $this->createSign([$this->auth, $this->loginId, $time ,$this->appSecret]);
        $params['sign'] = $signature;
        $result = dogGetCurl($this->apiDomain.'ashx/account/setScore.ashx', $params);
        if($result['code'] != 0 || !$result['success']){
            throw new GameException($result['msg'], 0);
        }
        // 记录玩家钱包转出转入记录
        $this->createWalletTransfer($type, $amount, $reward, $params['orderid']);
        return $result;
    }

    /**
     * 查询游戏纪录
     * @return array|mixed|Response
     * @throws GameException|\think\Exception
     */
    public function getGameRecordList(string $startTime = '', string $endTime = '', $uuid, int $page = 1, int $pageSize = 1000)
    {
        $time = round(microtime(true)*1000);
        $params = [
            'pageIndex' => $page,
            'pageSize' => $pageSize,
            'userName' => $this->loginId,
            'sDate' => $startTime,
            'eDate' => $endTime,
            'time' => $time,
            'authcode' => $this->auth,
        ];
        $signature = $this->createSign([$this->auth, $this->loginId, $time ,$this->appSecret]);
        $params['sign'] = $signature;
        $result = dogGetCurl($this->apiDomain, $params);
        if($result['code'] == 0 || !$result['success']){
            throw new GameException($result['msg'], 0);
        }
        return $result;
    }

    /**
     * 查询全部玩家账单
     * @return array|mixed|Response
     * @throws GameException|\think\Exception
     */
    public function getReportRecord(string $startTime = '', string $endTime = '')
    {
        $time = round(microtime(true)*1000);
        $params = [
            'userName' => $this->admin_user,
            'sDate' => $startTime,
            'eDate' => $endTime,
            'Type' => 'ServerTotalReport',
            'time' => $time,
            'authcode' => $this->auth,
        ];
        $signature = $this->createSign([$this->auth, $this->admin_user, $time ,$this->appSecret]);
        $params['sign'] = $signature;
        $result = dogGetCurl($this->recordApi.'ashx/AgentTotalReport.ashx', $params);
        if(!$result['success'] && !empty($result['results'])){
            throw new GameException($result['msg'], 0);
        }
        return $result['results'];
    }

    /**
     * 查询单个玩家单日输赢
     * @return array|mixed|Response
     * @throws GameException|\think\Exception
     */
    public function getAccountReport(string $startTime = '', string $endTime = '', $playerCode)
    {
        $time = round(microtime(true)*1000);
        $params = [
            'userName' => $playerCode,
            'sDate' => $startTime,
            'eDate' => $endTime,
            'time' => $time,
            'authcode' => $this->auth,
        ];
        $signature = $this->createSign([$this->auth, $playerCode, $time ,$this->appSecret]);
        $params['sign'] = $signature;
        $result = dogGetCurl($this->apiDomain.'ashx/AccountReport.ashx', $params);
        if($result['code'] == 0 || !$result['success']){
            throw new GameException($result['msg'], 0);
        }
        return $result;
    }

    /**
     * 查询玩家游戏记录
     * @return array
     */
    public function handleOrderHistories(): array
    {
        try {
            $list = [];
            $startTime = date('Y-m-d');
            $endTime = date('Y-m-d');
            $data = $this->getReportRecord($startTime, $endTime);
            if (!empty($data)) {
                foreach ($data as $item) {
                    $list[] = [
                        'player_code' => $item['Account'],
                        'platform_id' => $this->platform->id,
                        'game_code' => 'Kiss918',
                        'bet' => $item['press'],
                        'win' => $item['win'],
                        'order_no' => $item['idx'].date('Ymd'),
                        'original_data' => json_encode($item,JSON_UNESCAPED_UNICODE),
                        'platform_action_at' => $startTime,
                        'game_type' => 1,
                        'created_at' => date('Y-m-d H:i:s'),
                        'updated_at' => date('Y-m-d H:i:s'),
                    ];

                }
            }
        } catch (Exception $e) {
            return [];
        }
        return $list;
    }

}