package robot.mj;

import com.taurus.core.entity.ITArray;
import com.taurus.core.entity.ITObject;
import com.taurus.core.entity.TObject;
import com.taurus.core.events.Event;
import com.taurus.core.events.IEventListener;
import com.taurus.core.plugin.redis.Redis;
import com.taurus.core.util.ICallback;
import com.taurus.core.util.Logger;
import com.taurus.core.util.StringUtil;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
import robot.mj.info.RobotRoomInfo;
import taurus.client.Message;
import taurus.client.MessageResponse;
import taurus.client.TaurusClient;
import taurus.client.SocketCode;
import redis.clients.jedis.Jedis;
import robot.mj.handler.HuNanChangSha;
import taurus.util.ChangShaSuanFaTest;
import taurus.util.TinHuChi;

import java.util.*;
import java.util.concurrent.*;

/**
 * 机器人连接管理器 - 管理与游戏服务器的连接
 */
public class RobotConnectionManager {

    private Logger log = Logger.getLogger(RobotConnectionManager.class);
    private Map<String, TaurusClient> gameClients;
    //存储全局的长沙麻将AI处理器
    private HuNanChangSha huNanChangSha;

    private final String host="8.134.76.43";
    private final int port=6311;

    // 自动重连相关
    private final ScheduledExecutorService reconnectScheduler = Executors.newScheduledThreadPool(2);
    private final Map<String, Boolean> activeConnections = new ConcurrentHashMap<>();//记录活跃连接
    private final Map<String, Integer> reconnectAttempts = new ConcurrentHashMap<>();//重连尝试次数
    private final Map<String, Long> lastActivityTime = new ConcurrentHashMap<>();//记录最后活动时间
    private final Map<String, ScheduledFuture<?>> connectionWatchers = new ConcurrentHashMap<>();//连接监视器
    private final Map<String, Long> lastDisconnectTime = new ConcurrentHashMap<>();//记录最后断开时间
    private final Map<String, IEventListener> connectEventListeners = new ConcurrentHashMap<>();//连接事件监听器
    private final Map<String, IEventListener> messageEventListeners = new ConcurrentHashMap<>();//消息事件监听器
    private final int MAX_RECONNECT_ATTEMPTS = 3;//最大重连次数（减少重试）
    private final int RECONNECT_DELAY_SECONDS = 5;//重连间隔秒数（增加延迟）
    private final int CONNECTION_WATCH_INTERVAL = 15;//连接监视间隔秒数（延长检测间隔）
    private final int CONNECTION_TIMEOUT_SECONDS = 45;//连接超时检测秒数（延长超时时间）
    private final int MIN_RECONNECT_INTERVAL = 60;//最小重连间隔秒数（防止频繁重连）

    /*长沙麻将游戏算法相关 start*/
    private Map<Integer, List<Integer>> playerOutcardsMap = new HashMap<>();
    private Map<Integer, List<Integer>> playerchisMap = new HashMap<>();
    private Map<Integer, List<Integer>> playerpengsMap = new HashMap<>();
    private Map<Integer, List<Integer>> playermingsMap = new HashMap<>();
    private Map<Integer, List<Integer>> playerzisMap = new HashMap<>();
    private int groupId = 0;
    private int pid = 0;
    private int playerId = 0;
    private String playKey = "";
    private Map<Integer, Integer> count = new HashMap<Integer, Integer>();
    /*长沙麻将游戏算法相关 end*/


    public RobotConnectionManager() {
        gameClients = new HashMap<>();
        huNanChangSha = new HuNanChangSha();
    }

    /**
     * 启动连接监视器
     */
    private void startConnectionWatcher(String connecId) {
        //检查是否有运行中的监视器
        ScheduledFuture<?> existingWatcher = connectionWatchers.get(connecId);
        if (existingWatcher != null && !existingWatcher.isDone()) {
            existingWatcher.cancel(false);
        }

        TaurusClient client = gameClients.get(connecId);
        if (client == null || !client.isConnected()) {
            System.out.println("连接不存在或未激活，不启动监视器: {"+connecId+"}");
            return;
        }

        //启动监视器
        ScheduledFuture<?> watcher = reconnectScheduler.scheduleAtFixedRate(() -> {
            try {
                monitorConnection(connecId);
            } catch (Exception e) {
                System.out.println("连接监视器执行异常: {"+connecId+"} " + e.getMessage());
            }
        }, CONNECTION_WATCH_INTERVAL, CONNECTION_WATCH_INTERVAL, TimeUnit.SECONDS);

        connectionWatchers.put(connecId, watcher);
        System.out.println("启动连接监视器: {"+connecId+"}, 检测间隔: {"+CONNECTION_WATCH_INTERVAL+"}秒");
    }

    /**
     * 监视连接状态
     */
    private void monitorConnection(String connecId) {
        TaurusClient client = gameClients.get(connecId);
        if (client == null) {
            System.out.println("监视器找不到客户端连接: {"+connecId+"}");
            stopConnectionWatcher(connecId);
            return;
        }

        // 检查连接状态
        if (!client.isConnected()) {
            System.out.println("监视器检测到连接断开: {"+connecId+"}");
            handleConnectionFailure(connecId, SocketCode.Disconnect);
            return;
        }

        // 检查是否超时（基于最后活动时间）
        Long lastActivity = lastActivityTime.get(connecId);
        if (lastActivity != null) {
            long elapsed = System.currentTimeMillis() - lastActivity;
            if (elapsed > CONNECTION_TIMEOUT_SECONDS * 1000) {
                System.out.println("连接超时检测: {"+connecId+"}, elapsed: {"+elapsed+"}ms");
                // 尝试发送验证消息
                try {
                    ITObject params = TObject.newInstance();
                    params.putString("pos", "10,10");
                    client.send("1001", params, response -> {
                        // 更新活动时间
                        lastActivityTime.put(connecId, System.currentTimeMillis());
                    });
                } catch (Exception e) {
                    System.out.println("连接验证失败，触发重连: {"+connecId+"}");
                    handleConnectionFailure(connecId, SocketCode.NetworkException);
                }
            }
        }
    }

    /**
     * 移除事件监听器
     */
    private void removeEventListeners(String connecId) {
        TaurusClient client = gameClients.get(connecId);
        if (client != null) {
            IEventListener messageListener = messageEventListeners.remove(connecId);
            IEventListener connectListener = connectEventListeners.remove(connecId);
            
            if (messageListener != null) {
                client.removeEventListener(TaurusClient.NetClientEvent.OnEvent, messageListener);
            }
            if (connectListener != null) {
                client.removeEventListener(TaurusClient.NetClientEvent.Connect, connectListener);
            }
        }
        System.out.println("移除事件监听器: {"+connecId+"}");
    }

    /**
     * 停止连接监视器
     */
    private void stopConnectionWatcher(String connecId) {
        ScheduledFuture<?> watcher = connectionWatchers.remove(connecId);
        if (watcher != null && !watcher.isDone()) {
            watcher.cancel(false);
        }
        System.out.println("停止连接监视器定时任务: {"+connecId+"}");
    }

    /**
     * 设置会话和令牌
     */
    public void setSessionAndToken(String session, String token) {
        huNanChangSha.session = session;
        huNanChangSha.token = token;
    }

    /**
     * 连接到长沙麻将游戏服务器
     */
    public TaurusClient connectToGameServer(String connecId) {
        try {
            //检查是否已经连接
            if (gameClients.containsKey(connecId)) {
                TaurusClient existingClient = gameClients.get(connecId);
                if (existingClient.isConnected()) {
                    return existingClient;
                }
                //todo: 断线重连
                /*else {
                    //连接断开 移除旧的客户端
                    disconnectFromGameServer(connecId);
                }*/
            }

            //创建Taurus客户端
            TaurusClient client = new TaurusClient(host + ":" + port, "game", TaurusClient.ConnectionProtocol.Tcp);

            // 设置事件监听器
            setupEventListeners(client, connecId);

            client.connect();

            gameClients.put(connecId, client);
            activeConnections.put(connecId, true);
            reconnectAttempts.remove(connecId);
            lastActivityTime.put(connecId, System.currentTimeMillis()); // 记录连接建立时间

            return client;
        } catch (Exception e) {
            log.error("连接到游戏服务器时发生异常", e);
            return null;
        }
    }

    /**
     * 断开与游戏服务器的连接（主动断开）
     */
    public void disconnectFromGameServer(String connecId) {
        System.out.println("开始主动断开连接: {"+connecId+"}");
        
        //主动断开 标记为非活跃连接
        activeConnections.put(connecId, false);
        reconnectAttempts.remove(connecId);
        lastActivityTime.remove(connecId);
        lastDisconnectTime.put(connecId, System.currentTimeMillis());

        //停止连接监视器
        stopConnectionWatcher(connecId);

        //移除事件监听器
        removeEventListeners(connecId);

        TaurusClient client = gameClients.remove(connecId);
        if (client != null) {
            try {
                if (client.isConnected()) {
                    client.killConnection();
                }
                System.out.println("客户端主动断开连接完成: {"+connecId+"}");
            } catch (Exception e) {
                System.out.println("断开客户端连接时发生异常: " + connecId + ", 错误: " + e.getMessage());
            }
        } else {
            System.out.println("客户端连接不存在: {"+connecId+"}");
        }
    }

    /**
     * 增加leftover_robot数量 机器人退出空房间的情况
     */
    private void updateLeftoverRobot(String groupId, String wanfaId, int robotId) {
        try (Jedis jedis11 = Redis.use("group1_db11").getJedis();Jedis jedis2 = Redis.use("group1_db2").getJedis()) {
            String playKey = "g{" + groupId + "}:play:" + wanfaId;
            jedis11.hincrBy(playKey, "leftover_robot", 1);

            jedis2.hset("{grobot}:" + robotId, "start", "0");

            System.out.println("机器人 {"+robotId+"} 退出空房间，增加leftover_robot，群组={"+groupId+"}, 玩法={"+wanfaId+"}");
        }
    }

    /**
     * 处理连接失败或断开事件
     */
    private void handleConnectionFailure(String connecId, SocketCode code) {
        System.out.println("处理连接失败或断开事件: {"+connecId+"}, 错误码: {"+code+"}");

        //非主动断开才进行重连
        if (activeConnections.getOrDefault(connecId, false)) {
            scheduleReconnect(connecId);
        }
    }

    /**
     * 安排重连任务
     */
    private void scheduleReconnect(String connecId) {
        //检查是否仍然是活跃连接
        if (!activeConnections.getOrDefault(connecId, false)) {
            System.out.println("连接已非活跃，取消重连安排: {"+connecId+"}");
            return;
        }
        
        Integer attempts = reconnectAttempts.getOrDefault(connecId, 0);
        //最大重连次数
        if (attempts >= 5) {
            System.out.println("达到最大重连次数，停止重连: {"+connecId+"}");
            activeConnections.put(connecId, false);
            return;
        }

        reconnectAttempts.put(connecId, attempts + 1);
        System.out.println("安排重连任务: {"+connecId+"}, 第{"+(attempts + 1)+"}次尝试");

        reconnectScheduler.schedule(() -> {
            try {
                //再次检查连接状态
                if (activeConnections.getOrDefault(connecId, false)) {
                    System.out.println("开始重连: {"+connecId+"}");
                    reconnectToGameServer(connecId);
                } else {
                    System.out.println("重连前检查发现连接已非活跃，取消重连: {"+connecId+"}");
                }
            } catch (Exception e) {
                System.out.println("重连失败: {"+connecId+"}, 错误: " + e.getMessage());
            }
        }, 1, TimeUnit.SECONDS);//重连间隔秒
    }

    /**
     * 重新连接到游戏服务器
     */
    private void reconnectToGameServer(String connecId) {
        //检查是否仍然是活跃连接
        if (!activeConnections.getOrDefault(connecId, false)) {
            System.out.println("连接已标记为非活跃，取消重连: {"+connecId+"}");
            return;
        }

        try {
            //检查是否已经有连接
            TaurusClient existingClient = gameClients.get(connecId);
            if (existingClient != null && existingClient.isConnected()) {
                System.out.println("连接已恢复，取消重连: {"+connecId+"}");
                reconnectAttempts.remove(connecId);
                return;
            }

            //移除旧的客户端和事件监听器
            if (existingClient != null) {
                try {
                    existingClient.killConnection();
                } catch (Exception e) {
                    System.out.println("关闭旧连接时发生异常: {"+connecId+"}");
                }
                gameClients.remove(connecId);
            }
            //清理旧的事件监听器
            removeEventListeners(connecId);

            //创建新连接
            TaurusClient client = new TaurusClient(host + ":" + port, "game", TaurusClient.ConnectionProtocol.Tcp);

            //设置新的事件监听器
            setupEventListeners(client, connecId);

            client.connect();
            gameClients.put(connecId, client);
            lastActivityTime.put(connecId, System.currentTimeMillis());

            System.out.println("重连成功: {"+connecId+"}");
            reconnectAttempts.remove(connecId);

            //重连成功后重新启动监视器
            startConnectionWatcher(connecId);
        } catch (Exception e) {
            log.error("重连过程中发生异常: " + connecId, e);
            //检查是否仍然是活跃连接后再安排下次重连
            if (activeConnections.getOrDefault(connecId, false)) {
                scheduleReconnect(connecId);
            }
        }
    }

    /**
     * 设置事件监听器
     */
    private void setupEventListeners(TaurusClient client, String connecId) {
        // 先移除可能存在的旧监听器
        removeEventListeners(connecId);
        
        // 添加消息事件监听器
        IEventListener messageListener = new IEventListener() {
            @Override
            public void handleEvent(Event event) {
                //检查连接是否仍然有效
                if (!activeConnections.getOrDefault(connecId, false)) {
                    System.out.println("消息监听器: 连接已非活跃，忽略消息: {"+connecId+"}");
                    return;
                }
                
                //获取 msg
                Message message = (Message) event.getParameter("msg");

                // 更新最后活动时间
                lastActivityTime.put(connecId, System.currentTimeMillis());

                ITObject param = message.param;
                //回调协议号
                String command = message.command;
                System.out.println("csmj OnEvent msg： " + command);

                //根据玩法ID处理不同的回调
                if (StringUtil.isNotEmpty(command)) {
                    //直接处理协议
                    handleProtocol(command, message, client, connecId);
                }
            }
        };

        //添加连接状态监听器
        IEventListener connectListener = new IEventListener() {
            @Override
            public void handleEvent(Event event) {
                //检查连接是否仍然应该处理事件
                if (!activeConnections.getOrDefault(connecId, false)) {
                    System.out.println("连接监听器: 连接已标记为非活跃，忽略状态变更: {"+connecId+"}");
                    return;
                }
                
                Message message = (Message) event.getParameter("msg");
                SocketCode code = (SocketCode) event.getParameter("code");
                
                if (code == SocketCode.Connect) {
                    System.out.println("csmj Connect connecId: " + connecId);
                    //连接成功 标记为活跃连接并重置重连次数
                    activeConnections.put(connecId, true);
                    reconnectAttempts.remove(connecId);
                    lastActivityTime.put(connecId, System.currentTimeMillis());
                    lastDisconnectTime.remove(connecId);
                    System.out.println("连接成功: {"+connecId+"} ");

                    //启动该连接的监视器
                    if (!connectionWatchers.containsKey(connecId)) {
                        startConnectionWatcher(connecId);
                    }
                } else {
                    //连接失败或断开
                    System.out.println("连接状态异常: {"+connecId+"}, code: {"+code+"}");
                    if (activeConnections.getOrDefault(connecId, false)) {
                        //断开活跃连接
                        handleConnectionFailure(connecId, code);
                    }
                }
            }
        };

        //注册事件监听器
        client.addEventListener(TaurusClient.NetClientEvent.OnEvent, messageListener);
        client.addEventListener(TaurusClient.NetClientEvent.Connect, connectListener);
        
        //保存监听器引用以便后续移除
        messageEventListeners.put(connecId, messageListener);
        connectEventListeners.put(connecId, connectListener);
    }

    /**
     * 快速检测连接状态并触发重连
     */
    public void quickCheckAndReconnect(String connecId) {
        TaurusClient client = gameClients.get(connecId);
        if (client != null) {
            //检查连接状态和超时
            if (!client.isConnected()) {
                System.out.println("快速检测到连接断开: {"+connecId+"} ");
                handleConnectionFailure(connecId, SocketCode.Disconnect);
            } else {
                //检查是否超时（基于最后活动时间）
                Long lastActivity = lastActivityTime.get(connecId);
                if (lastActivity != null) {
                    long elapsed = System.currentTimeMillis() - lastActivity;
                    if (elapsed > CONNECTION_TIMEOUT_SECONDS * 1000) {
                        System.out.println("连接超时检测: {"+connecId+"} , elapsed: {"+elapsed+"}ms");
                        //尝试发送一个简单消息来验证连接
                        try {
                            ITObject params = TObject.newInstance();
                            params.putString("pos", "10,10");
                            client.send("1001", params, response -> {
                                //更新活动时间
                                lastActivityTime.put(connecId, System.currentTimeMillis());
                            });
                        } catch (Exception e) {
                            System.out.println("连接验证失败，触发重连: : {"+connecId+"}");
                            handleConnectionFailure(connecId, SocketCode.NetworkException);
                        }
                    }
                }
            }
        }
    }

    /**
     * 处理接收到的游戏协议
     */
    private void handleProtocol(String command, Message message, TaurusClient client, String connecId) {
        ITObject param = message.param;
        try (Jedis jedis0 = Redis.use().getJedis()){
            //长沙麻将 机器人处理事件

            //[TCP->822] data:{"tip_list":[{"type":8,"id":1,"opcard":[],"weight":8,"card":0}],"types":[{"type":21,"value":1}]}
            //板胡Event [TCP->823] data:{"type":8,"seat":1,"data":[{"opcard":[204,204,204,108,108,108],"type":21,"value":1}]}
            if ("811".equalsIgnoreCase(command)) {//初始化收手牌

                huNanChangSha.cardInHead(command, message, client);
            } else if ("812".equalsIgnoreCase(command)) {//出牌广播
                //{"opzicards":[{"opzicards":[],"playerId":101555}],"opmingcards":[{"opmingcards":[],"playerId":101555}],"outcard_map":[{"outcards":[209,205],"playerId":101555},{"outcards":[],"playerId":112233}],"card":205,"opchicards":[{"opchicards":[105,103],"playerId":101555}],"oppengcards":[{"oppengcards":[],"playerId":101555}],"seat":1}
                ITArray outcard_map = param.getTArray("outcard_map");
                ITArray opchicards = param.getTArray("opchicards");
                ITArray oppengcards = param.getTArray("oppengcards");
                ITArray opmingcards = param.getTArray("opmingcards");
                ITArray opzicards = param.getTArray("opzicards");

                // 清空旧数据，用新数据完全覆盖
                playerOutcardsMap.clear();
                playerchisMap.clear();
                playerpengsMap.clear();
                playermingsMap.clear();
                playerzisMap.clear();
                //出过的牌
                if (outcard_map != null) {
                    for (int i = 0; i < outcard_map.size(); i++) {
                        ITObject playerData = outcard_map.getTObject(i);
                        int playerId = playerData.getInt("playerId");
                        ITArray outcardsArray = playerData.getTArray("outcards");

                        // 转换为List<Integer>
                        List<Integer> outcardsList = new ArrayList<>();
                        for (int j = 0; j < outcardsArray.size(); j++) {
                            outcardsList.add(outcardsArray.getInt(j));
                        }

                        // 存储到Map中（覆盖旧数据）
                        playerOutcardsMap.put(playerId, outcardsList);

                    }
                }

                //吃的牌
                if (opchicards != null) {
                    for (int i = 0; i < opchicards.size(); i++) {
                        ITObject playerData = opchicards.getTObject(i);
                        int playerId = playerData.getInt("playerId");
                        ITArray outchiArray = playerData.getTArray("opchicards");

                        List<Integer> outchiList = new ArrayList<>();
                        for (int j = 0; j < outchiArray.size(); j++) {
                            outchiList.add(outchiArray.getInt(j));
                        }
                        playerchisMap.put(playerId, outchiList);
                    }
                }

                //碰的牌
                if (oppengcards != null) {
                    for (int i = 0; i < oppengcards.size(); i++) {
                        ITObject playerData = oppengcards.getTObject(i);
                        int playerId = playerData.getInt("playerId");
                        ITArray outpengArray = playerData.getTArray("oppengcards");

                        List<Integer> outpengList = new ArrayList<>();
                        for (int j = 0; j < outpengArray.size(); j++) {
                            outpengList.add(outpengArray.getInt(j));
                        }
                        playerpengsMap.put(playerId, outpengList);
                    }
                }

                //明杠的牌
                if (opmingcards != null) {
                    for (int i = 0; i < opmingcards.size(); i++) {
                        ITObject playerData = opmingcards.getTObject(i);
                        int playerId = playerData.getInt("playerId");
                        ITArray outmingArray = playerData.getTArray("opmingcards");

                        List<Integer> outmingList = new ArrayList<>();
                        for (int j = 0; j < outmingArray.size(); j++) {
                            outmingList.add(outmingArray.getInt(j));
                        }
                        playermingsMap.put(playerId, outmingList);
                    }
                }

                //暗杠的牌
                if (opzicards != null) {
                    for (int i = 0; i < opzicards.size(); i++) {
                        ITObject playerData = opzicards.getTObject(i);
                        int playerId = playerData.getInt("playerId");
                        ITArray outziArray = playerData.getTArray("opzicards");

                        List<Integer> outziList = new ArrayList<>();
                        for (int j = 0; j < outziArray.size(); j++) {
                            outziList.add(outziArray.getInt(j));
                        }
                        playerzisMap.put(playerId, outziList);
                    }
                }

                HuNanChangSha.drawCard(command, message);
            } else if ("819".equalsIgnoreCase(command)) {
                //摸牌
                huNanChangSha.getCard(command, message,null,null);
            } else if ("813".equalsIgnoreCase(command)) {//出牌提示

                huNanChangSha.outCard(client,playerOutcardsMap,playerchisMap,playerpengsMap,playermingsMap,playerzisMap);
            }
            //放招提示
            else if ("814".equalsIgnoreCase(command)) {
                huNanChangSha.actionCard(param, client);
            }
            //2026.02.03修改 玩家加入房间
            else if ("2001".equalsIgnoreCase(command)) {
                String[] robotId = connecId.split("_", 2);
                RobotRoomInfo robotRoomInfo = EXGameController.getRobotRoomInfo(robotId[0]);
                Integer userId = param.getInt("aid");
                robotRoomInfo.setUserId(userId);
                System.out.println("玩家{"+robotRoomInfo.getRoomId()+"}加入房间:"+ param);
            }
            //2026.02.03修改 玩家退出房间也要检查
            else if ("2002".equalsIgnoreCase(command)) {
                CompletableFuture.runAsync(() -> {
                    try {
                        Integer userId = param.getInt("aid");
                        String[] robotIds= connecId.split("_", 2);
                        int robotId = Integer.parseInt(robotIds[0]);
                        RobotRoomInfo robotRoomInfo = EXGameController.getRobotRoomInfo(robotIds[0]);
                        Thread.sleep(6000);

                        if (userId.equals(robotRoomInfo.getUserId())) {
                            String roomKey = robotRoomInfo.getRoomId();

                            //查询该房间的玩家信息
                            String playersStr = jedis0.hget(roomKey, "players");
                            if (!playersStr.equals("[]")) {
                                String players = playersStr.substring(1, playersStr.length() - 1);
                                String[] playerIds = players.split(",");

                                //判断只有当前机器人一个玩家
                                if (playerIds.length == 1) {
                                    int playerId = Integer.parseInt(playerIds[0].trim());
                                    if (playerId == robotId) {

                                        String gpid = jedis0.hget(roomKey, "gpid");
                                        String gpId = jedis0.hget(roomKey, "group");

                                        //更新机器人剩余数量
                                        if (count != null && count.containsKey(Integer.parseInt(gpid))) {
                                            Integer currentValue = count.get(Integer.parseInt(gpid));
                                            if (currentValue > 0) {
                                                count.put(Integer.parseInt(gpid), currentValue - 1);
                                            }
                                        }

                                        //发送退出房间协议
                                        ITObject params = TObject.newInstance();
                                        client.send("1005", params, response -> {
                                            EXGameController.removeRobotRoomInfo(String.valueOf(robotId));
                                            //更新机器人剩余数量
                                            updateLeftoverRobot(gpId, gpid, robotId);
                                            System.out.println("2002发送退出房间协议1005，robotId: {"+robotId+"}");
                                        });
                                    }
                                }
                            }
                        }
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                });
            }
            //2026.02.03修改 玩家解散房间
            else if ("2005".equalsIgnoreCase(command)) {
                CompletableFuture.runAsync(() -> {
                    String[] robotIds= connecId.split("_", 2);
                    int robotId = Integer.parseInt(robotIds[0]);
                    RobotRoomInfo robotRoomInfo = EXGameController.getRobotRoomInfo(String.valueOf(robotId));
                    ITArray playsList = param.getTArray("list");
                    for (int i = 0; i < playsList.size(); i++) {
                        ITObject playerData = playsList.getTObject(i);
                        Integer userId = playerData.getInt("aid");
                        if (userId.equals(robotId)) {
                            String roomKey = robotRoomInfo.getRoomId();
                            String gpid = jedis0.hget(roomKey, "gpid");
                            String gpId = jedis0.hget(roomKey, "group");
                            try {
                                Thread.sleep(25000);
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }
                            //更新机器人剩余数量
                            if (count != null && count.containsKey(Integer.parseInt(gpid))) {
                                Integer currentValue = count.get(Integer.parseInt(gpid));
                                if (currentValue > 0) {
                                    count.put(Integer.parseInt(gpid), currentValue - 1);
                                }
                            }
                            EXGameController.removeRobotRoomInfo(String.valueOf(robotId));
                            //更新机器人剩余数量
                            updateLeftoverRobot(gpId, gpid, robotId);
                            disconnectFromGameServer(connecId);
                            System.out.println("2005玩家发送解散房间协议，robotId: {"+robotId+"}");
                        }
                    }
                });
            }
            //2026.02.03修改 解散房间时候恢复机器人账号可以使用
            else if ("2008".equalsIgnoreCase(command)) {
                String[] robotIds= connecId.split("_", 2);
                int robotId = Integer.parseInt(robotIds[0]);
                RobotRoomInfo robotRoomInfo = EXGameController.getRobotRoomInfo(String.valueOf(robotId));
                String roomKey = robotRoomInfo.getRoomId();

                if (jedis0.exists(roomKey)) {
                    String gpid = jedis0.hget(roomKey, "gpid");
                    String gpId = jedis0.hget(roomKey, "group");
                    EXGameController.removeRobotRoomInfo(String.valueOf(robotId));
                    //更新机器人剩余数量
                    updateLeftoverRobot(gpId, gpid, robotId);
                    disconnectFromGameServer(connecId);
                    jedis0.del(roomKey);
                    System.out.println("2008结束房间，robotId: {"+robotId+"}");
                }
            }
            //2026.02.03修改 通过机器人房间映射直接获取房间信息
            else if ("2009".equalsIgnoreCase(command)) {
                CompletableFuture.runAsync(() -> {
                    try {
                        Integer robotId = param.getInt("aid");
                        Thread.sleep(6000);

                        RobotRoomInfo robotRoomInfo = EXGameController.getRobotRoomInfo(String.valueOf(robotId));
                        if (robotRoomInfo != null) {
                            String roomKey = robotRoomInfo.getRoomId();

                            //查询该房间的玩家信息
                            String playersStr = jedis0.hget(roomKey, "players");
                            if (!playersStr.equals("[]")) {
                                String players = playersStr.substring(1, playersStr.length() - 1);
                                String[] playerIds = players.split(",");

                                //判断只有当前机器人一个玩家
                                if (playerIds.length == 1) {
                                    int playerId = Integer.parseInt(playerIds[0].trim());
                                    if (playerId == robotId) {

                                        String gpid = jedis0.hget(roomKey, "gpid");
                                        String gpId = jedis0.hget(roomKey, "group");

                                        //更新机器人剩余数量
                                        if (count != null && count.containsKey(Integer.parseInt(gpid))) {
                                            Integer currentValue = count.get(Integer.parseInt(gpid));
                                            if (currentValue > 0) {
                                                count.put(Integer.parseInt(gpid), currentValue - 1);
                                            }
                                        }

                                        //发送退出房间协议
                                        ITObject params = TObject.newInstance();
                                        client.send("1005", params, response -> {
                                            EXGameController.removeRobotRoomInfo(String.valueOf(robotId));
                                            //断开连接
                                            disconnectFromGameServer(connecId);
                                            //更新机器人剩余数量
                                            updateLeftoverRobot(gpId, gpid, robotId);
                                            System.out.println("2009发送退出房间协议1005，robotId: {"+robotId+"}");
                                        });
                                    }
                                }
                            }
                        }
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                });
            }
            //结算
            else if ("817".equalsIgnoreCase(command)) {
                huNanChangSha.getChangShaCardInhand().clear();
                huNanChangSha.getChuGuoCardInhand().clear();
                huNanChangSha.getpongGroup().clear();
                huNanChangSha.getchowGroup().clear();
                TinHuChi.lastTingCount = 0;
                TinHuChi.isMoreThanLast = false;
                ChangShaSuanFaTest.isTin=false;
                ChangShaSuanFaTest.isChi=false;
                ChangShaSuanFaTest.isPeng=false;
                ChangShaSuanFaTest.tinCards.clear();
                Integer type = param.getInt("type");
                if (type == 1 || type == 2) { //为1为大结算 为2为解散
                    Jedis jedis11s = Redis.use("group1_db11").getJedis();
                    try {
                        String key = "g{" + groupId + "}:play:" + pid;
                        //  jedis11s.hincrBy(key, "leftover_robot", 1);
//
                        if (count != null && count.containsKey(pid)) {
                            Integer currentValue = count.get(pid);
                            if (currentValue > 0) {
                                count.put(pid, currentValue - 1);
                            }
                        }

                        //todo 可能要修改机器人状态
                        /*String sql = String.format("UPDATE `account` SET start = %d WHERE id = %d", 0, playerId);
                        try {
                            DataBase.use().executeUpdate(sql);
                        } catch (SQLException e) {
                            e.printStackTrace();
                        }*/
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        jedis11s.close();
                    }

                    if (count != null && count.containsKey(pid)) {
                        Integer value = count.get(pid);

                        // 如果找到了对应的 pid
                        Jedis jedis12 = Redis.use("group1_db11").getJedis();

                        String shangxianRobot = jedis12.hget(playKey, "shangxian_robot");
                        String leftoverRobot = jedis12.hget(playKey, "leftover_robot");

                                                /*if (shangxianRobot != null && leftoverRobot != null) {
                                                    if (value == 0) {
                                                        jedis12.hset(playKey, "leftover_robot", shangxianRobot);
                                                    }
                                                }*/
                        jedis12.close();
                    }
                }
//                                        playerState.pongGroups.clear();;
//                                        playerState.handCards.clear();
//                                        playerState.chiGroups.clear();
//                                        playerState.gangGroups.clear();;


                Thread.sleep(1000);

                ITObject params = TObject.newInstance();
                params.putString("session", client.getSession());
                //todo session + "," + token
                client.send("1003", params, new ICallback<MessageResponse>() {

                    @Override
                    public void action(MessageResponse messageResponse) {


                    }
                });

            }
            //服务器通知客户端有玩家执行了操作
            else if ("815".equalsIgnoreCase(command)) {
                //[TCP->815] data:{"playerid":101555,"card":104,"opcard":[105,103],"from_seat":2,"type":1,"opengang":false}
                huNanChangSha.shanchuchuguopai(param);
            }
            //换牌提示
            else if ("820".equalsIgnoreCase(command)) {
                huNanChangSha.changePlayer(command, message);
            }
            else if ("825".equalsIgnoreCase(command)) {
                ITObject params = TObject.newInstance();
                params.putInt("qi", 0);
                params.putInt("id", 1);
                client.send("612", params, response -> {

                });
            }
            else if ("822".equalsIgnoreCase(command)) {
                ITObject params = TObject.newInstance();
                //params.putInt("qi", 0);
                params.putInt("id", 1);
                //[TCP->822] data:{"tip_list":[{"type":8,"id":1,"opcard":[],"weight":8,"card":0}],"types":[{"type":21,"value":1}]}
                //板胡Event [TCP->823] data:{"type":8,"seat":1,"data":[{"opcard":[204,204,204,108,108,108],"type":21,"value":1}]}

                client.send("612", params, response -> {

                });
            }
            //听牌天听
            else if ("835".equalsIgnoreCase(command)) {
                ITObject params = TObject.newInstance();
                params.putInt("qi", 0);
                params.putInt("id", 1);
                client.send("612", params, response -> {

                });

            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    public Set<String> scanRooms(Jedis jedis, String pattern) {
        Set<String> keys = new HashSet<>();
        String cursor = "0";
        ScanParams scanParams = new ScanParams().match(pattern).count(100);

        do {
            ScanResult<String> scanResult = jedis.scan(cursor, scanParams);
            keys.addAll(scanResult.getResult());
            cursor = String.valueOf(scanResult.getCursor());
        } while (!cursor.equals("0"));

        return keys;
    }

    /**
     * 根据connecId获取游戏服务器连接
     */
    public TaurusClient getGameClient(String connecId) {
        return gameClients.get(connecId);
    }

    /**
     * 清理所有连接和资源
     */
    public void cleanupAllConnections() {
        System.out.println("开始清理所有连接和资源...");
        
        //标记所有连接为非活跃
        for (String connecId : activeConnections.keySet()) {
            activeConnections.put(connecId, false);
        }
        
        //断开所有连接
        for (String connecId : new ArrayList<>(gameClients.keySet())) {
            disconnectFromGameServer(connecId);
        }
        
        //停止所有监视器
        for (String connecId : new ArrayList<>(connectionWatchers.keySet())) {
            stopConnectionWatcher(connecId);
        }
        
        //关闭调度器
        reconnectScheduler.shutdown();
        try {
            if (!reconnectScheduler.awaitTermination(5, TimeUnit.SECONDS)) {
                reconnectScheduler.shutdownNow();
            }
        } catch (InterruptedException e) {
            reconnectScheduler.shutdownNow();
            Thread.currentThread().interrupt();
        }
        
        //清理所有缓存数据
        activeConnections.clear();
        reconnectAttempts.clear();
        lastActivityTime.clear();
        lastDisconnectTime.clear();
        connectionWatchers.clear();
        connectEventListeners.clear();
        messageEventListeners.clear();
        gameClients.clear();
        
        System.out.println("所有连接和资源清理完成");
    }

}