package com.group.robot.connect;

import com.group.robot.RobotManager;
import com.group.robot.RobotManagerInterface;
import com.group.robot.info.RobotInfo;
import com.taurus.core.plugin.database.DataBase;
import com.taurus.core.plugin.redis.Redis;
import com.taurus.core.util.Logger;
import redis.clients.jedis.Jedis;

import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 机器人端口连接处理类
 */
public class RobotDisconnect {

    private final Logger log = Logger.getLogger(RobotDisconnect.class);
    private final Set<Integer> disconnectingRobots = ConcurrentHashMap.newKeySet();
    private final Object lock = new Object();

    private final RobotManager robotManager;
    /**
     * 构造函数
     * @param robotManager 机器人管理器
     */
    public RobotDisconnect(RobotManager robotManager) {
        this.robotManager = robotManager;
    }

    /**
     * 统一断开机器人连接
     * @param robotId 机器人ID
     * @param groupId 群组ID
     * @param gameId 玩法ID
     * @param roomId 房间ID
     */
    public void disconnectRobot(int robotId, int groupId, int gameId, String roomId) {
        //检查是否已经在断开过程中
        if (disconnectingRobots.contains(robotId)) {
            log.debug("机器人 {} 已经在断开连接过程中，跳过重复操作", robotId);
            return;
        }
        synchronized (lock) {
            if (disconnectingRobots.contains(robotId)) {
                return;
            }
            disconnectingRobots.add(robotId);
        }
        try (Jedis jedis2 = Redis.use("group1_db2").getJedis()){
            log.info("开始断开机器人 {} 的连接（群组={}, 玩法={}, 房间={}）",robotId, groupId, gameId, roomId);

            //从连接列表中移除机器人信息
            RobotInfo robot = robotManager.getConnectedRobot(robotId);

            //处理对应游戏处理器断开连接
            if (robot != null) {
                RobotManagerInterface handler = robotManager.getGameHandler(robot.getWanfaId());
                if (handler != null) {
                    handler.disconnectRobot(robot);
                    log.debug("游戏处理器已断开机器人 {} 连接", robotId);
                }

                //释放机器人
                robot.setUsing(false);
                //恢复集合leftover_robot 再次分配leftover_robot计数
                robotManager.leftoverRobotRemoved(robotId);
                log.debug("机器人 {} 已被释放，可以重新分配", robotId);
            }

            //减少机器人使用数
            if (gameId > 0) {
                robotManager.decreaseRobotCount(gameId);
                log.debug("减少玩法 {} 的机器人使用数，机器人ID={}", gameId, robotId);
            }

            //更新Redis中的leftover_robot数量
            if (groupId > 0 && gameId > 0) {
                if (!robotManager.isLeftoverRobotRecovered(robotId)) {
                    updateRedisLeftoverRobot(groupId, gameId, robotId);
                }
            }

            //更新Redis2中的机器人start状态为0
            updateRobotDB(robotId, 0);

            log.info("机器人 {} 断开连接流程完成", robotId);
        } catch (Exception e) {
            log.error("统一断开机器人 {} 连接时发生异常", robotId, e);
        } finally {
            //从机器人断开列表中移除
            disconnectingRobots.remove(robotId);
        }
    }

    /**
     * 更新Redis中的leftover_robot数量
     */
    private void updateRedisLeftoverRobot(int groupId, int gameId, int robotId) {
        try (Jedis jedis11 = Redis.use("group1_db11").getJedis()) {
            String playKey = "g{" + groupId + "}:play:" + gameId;
            jedis11.hincrBy(playKey, "leftover_robot", 1);
            log.debug("更新Redis leftover_robot，群组={}, 玩法={}, 机器人={}", groupId, gameId, robotId);
        } catch (Exception e) {
            log.error("更新Redis leftover_robot时异常，群组={}, 玩法={}", groupId, gameId, e);
        }
    }



    /**
     * 更新redis及数据库状态
     */
    private void updateRobotDB(int robotId, int startValue) {
        try (Jedis jedis2 = Redis.use("group1_db2").getJedis()) {
            String gRobotKey = "{grobot}:" + robotId;
            jedis2.hset(gRobotKey, "start", String.valueOf(startValue));
            log.debug("Redis2已更新机器人 {} 的start状态为 {}", robotId, startValue);

            String sql = String.format("UPDATE `account` SET start = %d WHERE id = %d", startValue, robotId);
            DataBase.use().executeUpdate(sql);
            log.debug("数据库已更新机器人 {} 状态为可用", robotId);
        } catch (Exception e) {
            log.error("更新机器人 {} Redis2 start状态失败", robotId, e);
        }
    }

}
