<?php


namespace app\services\opening;


use app\models\bet\Bet;
use app\models\process\NumberTab;
use app\models\user\User;
use app\services\connect\InitTableService;
use app\services\waybill\WaybillRemindService;
use freedom\utils\CardPosition;
use freedom\utils\RedisUtil;
use freedom\utils\SocketSession;
use think\facade\Env;
use think\swoole\Websocket;

/**
 * TODO Dt开结果服务
 * Class OpeningDtService
 * @package app\services\opening
 */
class OpeningDtService
{

    /**
     * TODO Dt开结果处理
     * @param array $event
     * @param array $tableInfo
     * @param Websocket $ws
     * @return void
     */
    public static function openingDt(array $event, array $tableInfo, Websocket $ws)
    {
        //判断结果并推送结果
        $res = self::doOpening($event,$tableInfo);
        if ($res['status'] == false){
            $ws->emit('openingDt',['status' => false, 'msg' => $res['msg']]);
            return;
        }
        list($opening,$banker,$player,$lastNumberTabInfo,$newNumberTabInfo) = $res['data'];
        $round = array(
            'opening' => $opening,
            'banker' => $banker,
            'player' => $player,
            'boot_id' => $newNumberTabInfo['boot_id'],
            'boot_num' => $newNumberTabInfo['boot_num'],
            'number_tab_id' => $newNumberTabInfo['id'],
            'previous_number_tab_id' => $lastNumberTabInfo['id'],
            'number_tab_number' => $newNumberTabInfo['number'],
            'number_tab_status' => InitTableService::numberTabStatus($newNumberTabInfo)
        );
        $ws->emit('openingDt',['status' => true, 'table_id' => $tableInfo['id'], 'round' => $round]);
        $ws->to(SocketSession::HOUSE_NAME)->emit('openingDtResult',['status' => true, 'table_id' => $tableInfo['id'], 'round' => $round]);
        //处理注单
        self::doBet($ws,$tableInfo,$lastNumberTabInfo);
        //处理好路
        WaybillRemindService::parseWaybillRemind($tableInfo['game_id'], $tableInfo['id'], $tableInfo['table_name'], $newNumberTabInfo['boot_id']);
    }

    /**
     * TODO 判断结果
     * @param array $event
     * @param array $tableInfo
     * @return array
     */
    public static function doOpening(array $event, array $tableInfo): array
    {
        if (!isset($event['number_tab_id'])) return ['status' => false, 'msg' => 'opening_fail_2'];
        $numberTabId = intval($event['number_tab_id']);
        $numberTabInfo = NumberTab::getByTableIdOrderByIdDesc($tableInfo);
        if (!$numberTabInfo || $numberTabId != $numberTabInfo['id']) return ['status' => false, 'msg' => 'opening_fail_2'];
        if ($numberTabInfo['bet_status'] != 2) return ['status' => false, 'msg' => 'opening_fail_4'];
        $banker = null;
        $player = null;
        if ($tableInfo['is_scavenging'] == 1){
            $cardInfo = RedisUtil::getCardPosition($numberTabId);
            if (!$cardInfo || !isset($cardInfo['banker_1']) || !isset($cardInfo['player_1'])) return ['status' => false, 'msg' => 'opening_fail_6'];
            // 比较结果
            $banker = CardPosition::interchangeCard($cardInfo['banker_1']);
            $player = CardPosition::interchangeCard($cardInfo['player_1']);
            // 判断结果
            if($banker > $player){
                $opening = 1;
            }elseif($banker < $player){
                $opening = 2;
            }else{
                // 不对比花色
                $opening = 3;

                // 对比花色
//                if(CardPosition::interchangeColor($cardInfo['banker_1']) < CardPosition::interchangeColor($cardInfo['player_1'])){
//                    $opening = 1;
//                }elseif(CardPosition::interchangeColor($cardInfo['banker_1']) > CardPosition::interchangeColor($cardInfo['player_1'])){
//                    $opening = 2;
//                }else{
//                    $opening = 3;
//                }
            }
        }else{
            $opening = intval($event['bet']);
        }
        if (!in_array($opening,[1,2,3])) return ['status' => false, 'msg' => 'opening_fail_3'];
        //开盘
        $numberTabUpdate = ['result' => $opening, 'end_time' => time(), 'bet_status' => 3];
        $newNumberTabInfo = NumberTab::next($numberTabInfo,$numberTabUpdate,$tableInfo);
        if ($newNumberTabInfo){
            $lastNumberTabInfo = array_merge($numberTabInfo,$numberTabUpdate);
            return ['status' => true, 'data' => [$opening,$banker,$player,$lastNumberTabInfo,$newNumberTabInfo]];
        }else{
            return ['status' => false, 'msg' => 'opening_fail'];
        }
    }

    /**
     * TODO Bet处理
     * @param Websocket $ws  桌子信息
     * @param array $tableInfo  桌子信息
     * @param array $numberTabInfo  开结果的当前局信息
     * @return void
     */
    public static function doBet(Websocket $ws, array $tableInfo, array $numberTabInfo){
        $betArray = Bet::getByNumberTabIdValid($numberTabInfo['id']);
        foreach ($betArray AS $v){
            $userInfo = User::get(intval($v['user_id']));
            if (!$userInfo){
                continue;
            }
            $amount = $v['banker_amount'] + $v['player_amount'] + $v['tie_amount'];
            $winMoney = 0;
            // 双边洗码
            $ximaliang = 0;
            if($userInfo['type_xima'] == 1){
                $ximaliang = abs($v['banker_amount'] - $v['player_amount']);
            }
            // 龙赢
            if ($numberTabInfo['result'] == 1) {
                if($v['banker_amount'] > 0){
                    $winMoney = round($v['banker_amount'] * (1 + $userInfo['price_dragon']),2) + $winMoney;
                }
                // 单边洗码
                if($userInfo['type_xima'] == 2){
                    $ximaliang = $v['player_amount'];
                }
            }
            // 虎赢
            if ($numberTabInfo['result'] == 2) {
                if($v['player_amount'] > 0){
                    $winMoney = round($v['player_amount'] * (1 + $userInfo['price_tiger']),2) + $winMoney;
                }
                // 单边洗码
                if($userInfo['type_xima'] == 2){
                    $ximaliang = $v['banker_amount'];
                }
            }
            // 和
            if ($numberTabInfo['result'] == 3) {
                if (Env::get('system.dt_half') == 1) {
                    $winMoney = round(($v['banker_amount'] + $v['player_amount']) / 2, 2) + $winMoney;
                } else {
                    $winMoney = $v['banker_amount'] + $v['player_amount'] + $winMoney;
                }
                $ximaliang = 0;
                if ($v['tie_amount'] > 0) {
                    $winMoney = $v['tie_amount'] * (1 + $userInfo['price_tie_dt']) + $winMoney;
                }
            }
            // 计算最终赢钱金额
            $winTotal = $winMoney - $amount;
            /**
             * Model处理
             * @param array $tableInfo 桌子信息
             * @param array $betInfo bet信息
             * @param array $userInfo bet用户信息
             * @param array $numberTabInfo 局信息
             * @param float $amount 下注总数
             * @param float $winTotal 赢金额
             * @param float $ximaliang 洗码量
             */
            $res = Bet::openingBet($tableInfo,$v,$userInfo,$numberTabInfo,$amount,$winTotal,$ximaliang);
            if ($res['status']) {
                $tableUser = app('swoole.table.user');
                $userSession = $tableUser->get((string)$v['user_id']);
                if ($userSession && is_array($userSession)) {
                    $ws->setSender(0)->to($userSession['fd'])->emit('opening', ['status' => true, 'table_id' => $tableInfo['id'], 'round' => ['money' => $res['money'], 'win_total' => $winTotal, 'previous_number_tab_id' => $v['number_tab_id']]]);
                }
            }
        }
    }
}