<?php


namespace freedom\utils;


use app\models\table\Table;

/**
 * TODO swooleSession工具类
 * Class SocketSession
 * @package freedom\utils
 */
class SocketSession
{

    /**
     * 大房名称，所有有效连接都会加入
     * @var string
     */
    const HOUSE_NAME = 'house';
    /**
     * 控制台房间
     * @var string
     */
    const SPACE_ROOM_NAME = 'space';
    /**
     * 会员房间
     * @var string
     */
    const USER_ROOM_NAME = 'user';
    /**
     * 扫描房间
     * @var string
     */
    const SCAN_ROOM_NAME = 'scan';
    /**
     * 接口房间
     * @var string
     */
    const API_ROOM_NAME = 'api';

    /**
     * 经理房间
     * @var string
     */
    const MANAGER_ROOM_NAME = 'manager';

    /**
     * TODO 连接socket成功后保存session的工具方法，所有连接将加入house,不同连接模式加入不同的房间
     * @param array $event
     * @param string $mode
     * @return void;
     */
    public static function saveSocketSession(array $event, string $mode){
        $ws = app('\think\swoole\WebSocket');
        $fd = $ws->getSender();
        //保存信息到table
        $tableFd = app('swoole.table.fd');
        if($mode == 'space'){
            $tableSpace = app('swoole.table.space');
            $tableId = $event['table_id'];
            $tableName = $event['table_name'];
            //查找原本是否有登录
            $spaceInfo = $tableSpace->get((string) $tableId);
            if(!empty($spaceInfo)){
                $tableSpace->del((string) $tableId);
                $tableFd->del((string) $spaceInfo['fd']);
                $ws->setSender(0)->to($spaceInfo['fd'])->emit('RepeatedEntry',['status' => true, 'msg' => 'repeated_entry']);
            }
            $tableFd->set((string) $fd,[
                'mode' => 'space',
                'table_id' => $tableId,
                'table_name' => $tableName,
            ]);
            $tableSpace->set((string) $tableId,[
                'fd' => $fd,
                'mode' => 'space',
                'table_name' => $tableName,
            ]);
            $ws->join(self::SPACE_ROOM_NAME);
        }elseif($mode == 'scan'){
            $tableScan = app('swoole.table.scan');
            $appid = $event['appid'];
            //查找原本是否有登录
            $scanInfo = $tableScan->get((string) $appid);
            if(!empty($scanInfo)){
                $tableScan->del((string) $appid);
                $tableFd->del((string) $scanInfo['fd']);
                $ws->setSender(0)->to($scanInfo['fd'])->emit('RepeatedEntry',['status' => true, 'msg' => 'repeated_entry']);
            }
            $tableFd->set((string) $fd,[
                'mode' => 'scan',
                'scan_appid' => $appid,
            ]);
            $tableScan->set((string) $appid,[
                'fd' => $fd,
                'mode' => 'scan',
                'appid' => $appid,
            ]);
            $ws->join(self::SCAN_ROOM_NAME);
        }elseif($mode == 'user'){
            $tableUser = app('swoole.table.user');
            $user_id = $event['user_id'];
            $username = $event['username'];
            //查找原本是否有登录
            $userInfo = $tableUser->get((string) $user_id);
            if(!empty($userInfo)){
                $tableUser->del((string) $user_id);
                $tableFd->del((string) $userInfo['fd']);
                $ws->setSender(0)->to($userInfo['fd'])->emit('RepeatedEntry',['status' => true, 'msg' => 'repeated_entry']);
            }
            $tableFd->set((string) $fd,[
                'mode' => 'user',
                'user_id' => $user_id,
                'username' => $username,
            ]);
            $tableUser->set((string) $user_id,[
                'fd' => $fd,
                'mode' => 'user',
                'username' => $username,
                'isToBet' => 1,
                'toBetTime' => time(),
                'isToRob' => 1,
                'toRobTime' => time(),
                'isToCancelBet' => 1,
                'toCancelBetTime' => time(),
                'isToSeat' => 1,
                'toSeatTime' => time(),
                'isToLeaveSeat' => 1,
                'toLeaveSeatTime' => time(),
            ]);
            $ws->join(self::USER_ROOM_NAME);
        } elseif ($mode == 'api'){
            $tableApi = app('swoole.table.api');
            $appid = $event['appid'];
            //查找原本是否有登录
            $apiInfo = $tableApi->get((string) $appid);
            if(empty($scanInfo)){
                $tableApi->del((string) $appid);
                $tableFd->del((string) $apiInfo['fd']);
            }
            $tableFd->set((string) $fd,[
                'mode' => 'scan',
                'api_appid' => $appid,
            ]);
            $tableApi->set((string) $appid,[
                'fd' => $fd,
                'mode' => 'api',
                'appid' => $appid,
            ]);
            $ws->join(self::API_ROOM_NAME);
        } elseif ($mode == 'manager'){
            $tableManager = app('swoole.table.manager');
            $user_id = $event['user_id'];
            $username = $event['username'];

            //查找原本是否有登录
            $userInfo = $tableManager->get((string) $user_id);

            if(!empty($userInfo)){
                $tableManager->del((string) $user_id);
                $tableFd->del((string) $userInfo['fd']);
                $ws->setSender(0)->to($userInfo['fd'])->emit('RepeatedEntry',['status' => true, 'msg' => 'repeated_entry']);
            }
            $tableFd->set((string) $fd,[
                'mode' => 'manager',
                'user_id' => $user_id,
                'username' => $username,
            ]);

            $tableManager->set((string) $user_id,[
                'fd' => $fd,
                'mode' => 'manager',
                'username' => $username,
            ]);
            //电投用
            $ws->join(self::MANAGER_ROOM_NAME);
        }
        //加入房子
        $ws->join(self::HOUSE_NAME);
    }

    /**
     * TODO 检查房间是否存在有效连接
     * @param int $fd
     * @param string $mode
     * @return bool;
     */
    public static function checkSocketSession(int $fd, string $mode): bool
    {
        $tableFd = app('swoole.table.fd');
        $fdInfo = $tableFd->get((string) $fd);
        if(!empty($fdInfo)){
            if($mode == 'space' || $mode == 'sb'){
                $tableSpace = app('swoole.table.space');
                $spaceInfo = $tableSpace->get((string) $fdInfo['table_id']);
                if(!empty($spaceInfo)){
                    return true;
                }else{
                    return false;
                }
            }elseif($mode == 'scan'){
                $tableScan = app('swoole.table.scan');
                $scanInfo = $tableScan->get((string) $fdInfo['scan_appid']);
                if(!empty($scanInfo)){
                    return true;
                }else{
                    return false;
                }
            }elseif($mode == 'user'){
                $tableUser = app('swoole.table.user');
                $userInfo = $tableUser->get((string) $fdInfo['user_id']);
                if(!empty($userInfo)){
                    return true;
                }else{
                    return false;
                }
            }else{
                return false;
            }
        }else{
            return false;
        }
    }

    /**
     * TODO 事件执行的权限检查
     * @param array $event
     * @param string $mode
     * @return array;
     */
    public static function preliminaryCheck(array $event, string $mode): array
    {
        $ws = app('\think\swoole\WebSocket');
        $tableId = intval($event['table_id']);
        $tableInfo = Table::get($tableId);
        if ($mode == 'scan' && $tableInfo['scanner_type'] == 2) {
            $mode = 'sb';
        }
        if(SocketSession::checkSocketSession(intval($ws->getSender()),$mode) == false) {
            return ['status' => false, 'msg' => 'no_right'];
        }
        if(!$tableInfo) {
            return ['status' => false, 'msg' => 'not_table_data'];
        }
        return ['status' => true, 'data' => $tableInfo];
    }

    /**
     * TODO 检查是否重复提交
     * @param int $fd
     * @param string $mode
     * @param string $e
     * @return bool;
     */
    public static function checkRepeat(int $fd, string $mode, string $e): bool
    {
        $tableFd = app('swoole.table.fd');
        $fdInfo = $tableFd->get((string) $fd);
        if($mode == 'user'){
            $user_id = $fdInfo['user_id'];
            $tableUser = app('swoole.table.user');
            $userInfo = $tableUser->get((string) $user_id);
            if(!empty($userInfo)){
                if($e == 'isToBet'){
                    if($userInfo['isToBet'] == 1 || $userInfo['toBetTime'] <= (time() - 10)){
                        $userInfo['isToBet'] = 0;
                        $userInfo['toBetTime'] = time();
                        $tableUser->set((string) $user_id, $userInfo);
                        return true;
                    }else{
                        return false;
                    }
                }elseif($e == 'isToRob'){
                    if($userInfo['isToRob'] == 1 || $userInfo['toRobTime'] <= (time() - 10)){
                        $userInfo['isToRob'] = 0;
                        $userInfo['toRobTime'] = time();
                        $tableUser->set((string) $user_id, $userInfo);
                        return true;
                    }else{
                        return false;
                    }
                }elseif($e == 'isToCancelBet'){
                    if($userInfo['isToCancelBet'] == 1 || $userInfo['toCancelBetTime'] <= (time() - 10)){
                        $userInfo['isToCancelBet'] = 0;
                        $userInfo['toCancelBetTime'] = time();
                        $tableUser->set((string) $user_id, $userInfo);
                        return true;
                    }else{
                        return false;
                    }
                }elseif($e == 'isToSeat'){
                    if($userInfo['isToSeat'] == 1 || $userInfo['toSeatTime'] <= (time() - 10)){
                        $userInfo['isToSeat'] = 0;
                        $userInfo['toSeatTime'] = time();
                        $tableUser->set((string) $user_id, $userInfo);
                        return true;
                    }else{
                        return false;
                    }
                }elseif($e == 'isToLeaveSeat'){
                    if($userInfo['isToLeaveSeat'] == 1 || $userInfo['toLeaveSeatTime'] <= (time() - 10)){
                        $userInfo['isToLeaveSeat'] = 0;
                        $userInfo['toLeaveSeatTime'] = time();
                        $tableUser->set((string) $user_id, $userInfo);
                        return true;
                    }else{
                        return false;
                    }
                }else{
                    return false;
                }
            }else{
                return false;
            }
        }elseif($mode == 'space'){
            return false;
        }else{
            return false;
        }
    }
    /**
     * TODO 重置重复值
     * @param int $fd
     * @param string $mode
     * @param string $e
     * @return void;
     */
    public static function resetRepeat(int $fd, string $mode, string $e)
    {
        $tableFd = app('swoole.table.fd');
        $fdInfo = $tableFd->get((string) $fd);
        if($mode == 'user'){
            $user_id = $fdInfo['user_id'];
            $tableUser = app('swoole.table.user');
            $userInfo = $tableUser->get((string) $user_id);
            $userInfo[$e] = 1;
            $tableUser->set((string) $user_id, $userInfo);
        }
    }
}