package robot.mj.handler;

import com.robot.Util;
import com.taurus.core.entity.ITArray;
import com.taurus.core.entity.ITObject;
import com.taurus.core.entity.TArray;
import com.taurus.core.entity.TObject;
import com.taurus.core.plugin.redis.Redis;
import com.taurus.core.util.StringUtil;
import redis.clients.jedis.Jedis;
import taurus.client.Message;
import taurus.client.TaurusClient;
import taurus.util.*;

import java.util.*;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import static robot.mj.thread.ThreadPoolConfig.getBusinessThreadPool;

public class HuNanChangSha {

    public int changShaCard = 0;
    public static boolean isTinPeng = false;
    private final List<Integer> changShaCardInhandgang = new ArrayList<>();


    //长沙麻将出过的牌
    private final List<Integer> changShachuguopai = new ArrayList<>();

    private final List<Integer> changShaCardInhand = new ArrayList<>();

    public List<Integer> getChangShaCardInhand() {
        return changShaCardInhand;
    }

    private final Map<Integer, Integer> chuGuoPainum = new HashMap<>();


    //杠的牌
    private final List<Integer> gangdepai = new ArrayList<>();

    //碰牌
    private final List<Integer> pongGroup = new ArrayList<>();

    //吃牌
    private final List<Integer> chowGroup = new ArrayList<>();

    //会话标识
    public String session = "";
    //访问令牌
    public String token = "";


    private static ChangShaSuanFaTest changShaSuanFaTest = new ChangShaSuanFaTest();
    
    private static final Gson gson = new Gson();

    //公共的getter和setter方法
    public List<Integer> getgangdepai() {
        return gangdepai;
    }

    public List<Integer> getchangShaCardInhandgang() {
        return changShaCardInhandgang;
    }

    public List<Integer> getpongGroup() {
        return pongGroup;
    }

    public List<Integer> getchowGroup() {
        return chowGroup;
    }

    public List<Integer> getChuGuoCardInhand() {
        return changShachuguopai;
    }

    public Map<Integer, Integer> getChuGuoPainum() {
        return chuGuoPainum;
    }
    
    /**
     * 将当前实例状态序列化为JSON字符串并保存到Redis
     * @param connecId 连接ID
     */
    public void saveToRedis(String connecId) {
        Jedis jedis = Redis.use("group1_db2").getJedis();
        try {
            Map<String, String> stateMap = new HashMap<>();
            
            stateMap.put("changShaCardInhand", gson.toJson(changShaCardInhand));
            stateMap.put("changShachuguopai", gson.toJson(changShachuguopai));
            stateMap.put("chuGuoPainum", gson.toJson(chuGuoPainum));
            stateMap.put("gangdepai", gson.toJson(gangdepai));
            stateMap.put("pongGroup", gson.toJson(pongGroup));
            stateMap.put("chowGroup", gson.toJson(chowGroup));
            stateMap.put("changShaCardInhandgang", gson.toJson(changShaCardInhandgang));
            
            stateMap.put("changShaCard", String.valueOf(changShaCard));
            stateMap.put("session", session);
            stateMap.put("token", token);
            
            String redisKey = "{csmj}:" + connecId;
            jedis.hmset(redisKey, stateMap);
            //1小时过期时间
            jedis.expire(redisKey, 3600);

            System.out.println("保存HuNanChangSha状态到Redis: " + connecId);
        } catch (Exception e) {
            System.err.println("保存HuNanChangSha状态到Redis失败: " + e.getMessage());
        } finally {
            jedis.close();
        }
    }
    
    /**
     * 从Redis恢复实例状态
     * @param connecId 连接ID
     * @return 是否成功恢复
     */
    public boolean restoreFromRedis(String connecId) {
        Jedis jedis = Redis.use("group1_db2").getJedis();
        try {
            String redisKey = "{csmj}:" + connecId;
            Map<String, String> stateMap = jedis.hgetAll(redisKey);
            
            if (stateMap == null || stateMap.isEmpty()) {
                System.out.println("Redis中没有找到HuNanChangSha状态数据: " + connecId);
                return false;
            }
            
            //反序列化集合
            if (stateMap.containsKey("changShaCardInhand")) {
                changShaCardInhand.clear();
                List<Integer> handCards = gson.fromJson(stateMap.get("changShaCardInhand"), 
                    new TypeToken<List<Integer>>(){}.getType());
                if (handCards != null) changShaCardInhand.addAll(handCards);
            }
            
            if (stateMap.containsKey("changShachuguopai")) {
                changShachuguopai.clear();
                List<Integer> outCards = gson.fromJson(stateMap.get("changShachuguopai"), 
                    new TypeToken<List<Integer>>(){}.getType());
                if (outCards != null) changShachuguopai.addAll(outCards);
            }
            
            if (stateMap.containsKey("chuGuoPainum")) {
                chuGuoPainum.clear();
                Map<Integer, Integer> painum = gson.fromJson(stateMap.get("chuGuoPainum"), 
                    new TypeToken<Map<Integer, Integer>>(){}.getType());
                if (painum != null) chuGuoPainum.putAll(painum);
            }
            
            if (stateMap.containsKey("gangdepai")) {
                gangdepai.clear();
                List<Integer> gangCards = gson.fromJson(stateMap.get("gangdepai"), 
                    new TypeToken<List<Integer>>(){}.getType());
                if (gangCards != null) gangdepai.addAll(gangCards);
            }
            
            if (stateMap.containsKey("pongGroup")) {
                pongGroup.clear();
                List<Integer> pongCards = gson.fromJson(stateMap.get("pongGroup"), 
                    new TypeToken<List<Integer>>(){}.getType());
                if (pongCards != null) pongGroup.addAll(pongCards);
            }
            
            if (stateMap.containsKey("chowGroup")) {
                chowGroup.clear();
                List<Integer> chowCards = gson.fromJson(stateMap.get("chowGroup"), 
                    new TypeToken<List<Integer>>(){}.getType());
                if (chowCards != null) chowGroup.addAll(chowCards);
            }
            
            if (stateMap.containsKey("changShaCardInhandgang")) {
                changShaCardInhandgang.clear();
                List<Integer> gangHandCards = gson.fromJson(stateMap.get("changShaCardInhandgang"), 
                    new TypeToken<List<Integer>>(){}.getType());
                if (gangHandCards != null) changShaCardInhandgang.addAll(gangHandCards);
            }
            
            //恢复基本属性
            if (stateMap.containsKey("changShaCard")) {
                changShaCard = Integer.parseInt(stateMap.get("changShaCard"));
            }

            session = stateMap.getOrDefault("session", "");
            token = stateMap.getOrDefault("token", "");
            
            System.out.println("从Redis恢复HuNanChangSha状态成功: " + connecId + ", 手牌数量: " + changShaCardInhand.size());
            return true;
        } catch (Exception e) {
            System.err.println("从Redis恢复HuNanChangSha状态失败: " + e.getMessage());
            return false;
        } finally {
            jedis.close();
        }
    }
    
    /**
     * 从Redis清除实例状态
     * @param connecId 连接ID
     */
    public static void removeFromRedis(String connecId) {
        Jedis jedis = Redis.use("group1_db2").getJedis();
        try {
            String redisKey = "{csmj}:" + connecId;
            jedis.del(redisKey);
            System.out.println("从Redis删除HuNanChangSha状态: " + connecId);
        } catch (Exception e) {
            System.err.println("从Redis删除HuNanChangSha状态失败: " + e.getMessage());
        } finally {
            jedis.close();
        }
    }

    /**
     * 出牌广播协议 812
     *
     * @param command 协议号
     * @param message 消息对象
     * @return
     */
    public String drawCard(String command, Message message) {
        if (command.equalsIgnoreCase("812")) {
            ITObject param = message.param;
            if (param == null) {
                return null;
            }
            changShaCard = param.getInt("card");
        }
        return null;
    }


    /**
     * 摸牌协议 819
     *
     * @param command 协议号
     * @param message 消息对象
     * @return
     */
    public String getCard(String command, Message message) {
        if (command.equalsIgnoreCase("819")) {
            ITObject param = message.param;
            if (param == null) {
                return null;
            }
            Jedis jedis222 = Redis.use("group1_db2").getJedis();

            if (param.getInt("player") != null) {
                int drawnCard = param.getInt("card");
                changShaSuanFaTest.drawnCards = drawnCard;//存储摸到的牌
                changShaCardInhand.add(drawnCard);
                System.out.println("param.getInt(player)" + param.getInt("player") );
                System.out.println("摸到的牌 +++++++++  " + drawnCard);
            }

            jedis222.close();
        }
        return null;
    }

    /**
     * 初始化手牌协议 811
     *
     * @param command 协议号
     * @param message 消息对象
     * @return
     */

    public String cardInHead(String command, Message message) {
        if (command.equalsIgnoreCase("811")) {
            ITObject param = message.param;
            if (param == null) {
                return null;
            }
            ITArray cardList = param.getTArray("card_list");

            List<Integer> handCards = new ArrayList<>();
            for (int i = 0; i < cardList.size(); i++) {
                handCards.add(cardList.getInt(i));
            }

            for (int i = 0; i < cardList.size(); i++) {
                changShaCardInhand.add(cardList.getInt(i));
            }

            System.out.println("changShaCardInhand" + changShaCardInhand);

        }
        return null;
    }

    /**
     * 同步手牌
     * @param handCard
     */
    public void updateHandCard(List<Integer> handCard) {
        System.out.println("updateHandCard同步手牌:"+ handCard);
        changShaCardInhand.clear();
        System.out.println("updateHandCard同步手牌changShaCardInhand:"+ changShaCardInhand);
        changShaCardInhand.addAll(handCard);
        System.out.println("updateHandCard同步手牌add:"+ changShaCardInhand);
    }

    public void updateOutCard(List<Integer> outCard) {
        changShachuguopai.clear();
        changShachuguopai.addAll(outCard);
    }

    /**
     * 延迟执行吃碰胡动作，增加自然的停顿效果
     * @param client 客户端连接
     * @param params 动作参数
     */
    private void delayedActionCard(TaurusClient client, ITObject params, String actionName) {
        //使用线程池执行延迟动作
        getBusinessThreadPool().execute(() -> {
            try {
                int delaySeconds = 1 + new Random().nextInt(2);
                System.out.println("执行" + actionName + "动作，延迟" + delaySeconds + "秒");
                Thread.sleep(delaySeconds * 1000);
                
                client.send("612", params, response -> {
                    System.out.println(actionName + "动作发送完成");
                });
            } catch (Exception e) {
                System.err.println("执行" + actionName + "动作时发生异常: " + e.getMessage());
            }
        });
    }
    
    /**
     * 处理 吃，碰，杠，补，胡
     *
     * @param param
     * @param client
     * @return 吃
     * [TCP->814] data:{"tip_list":[{"type":1,"id":1,"opcard":[108,109],"weight":1,"card":107}]}
     * 吃 碰
     * {"tip_list":[{"type":1,"id":1,"opcard":[206,205],"weight":1,"card":207},{"type":2,"id":2,"opcard":[207],"weight":2,"card":207}]}
     * 碰补
     * {"tip_list":[{"type":2,"id":1,"opcard":[101],"weight":2,"card":101},{"type":3,"id":2,"opcard":[101],"weight":3,"card":101}]}
     * 补
     * [TCP->814] data:{"tip_list":[{"type":5,"id":1,"opcard":[101],"weight":3,"card":101}]}
     * 吃，碰，补，杠，
     * {"tip_list":[{"type":1,"id":1,"opcard":[206,204],"weight":1,"card":205},{"type":1,"id":2,"opcard":[206,207],"weight":1,"card":205},{"type":2,"id":3,"opcard":[205],"weight":2,"card":205},{"type":3,"id":4,"opcard":[205],"weight":3,"card":205},{"type":3,"id":5,"opcard":[205],"weight":4,"card":205}]}
     * 碰
     * {"tip_list":[{"type":2,"id":1,"opcard":[207],"weight":2,"card":207}]}
     * 补，杠
     * {"tip_list":[{"type":5,"id":1,"opcard":[207],"weight":3,"card":207},{"type":5,"id":2,"opcard":[207],"weight":4,"card":207}]}
     * <p>
     * //拟定：
     * 1、对应的提示事件遍历 实行假设做了处理之后的结果 对应结果的对象
     * boolean isTing    是否听牌
     * boolean canTing   能否听牌
     * int     tingNum   听多少张
     * int     isDaHu    是否大胡
     * int     guzhang   有多少孤章
     * int     lastHands 差多少手
     * int     id        tiplist id
     * List<Integer>     opcard
     * int     weight    tiplist weight
     * int     card      tiplist card
     * int     type      tiplist type
     * 2、通过遍历后的结果进行打分
     * 打分系统：
     * 已经听牌：   --->   40
     * 操作后能听   --->   20
     * 操作之后散听  --->   -50
     * 听多张，每一张：--->  3
     * 孤章，每一张：----> -3
     * 差手数：每一手  ----> -5
     * 操作之前是否大胡 ----> 10
     * 去掉大胡    -----> -10
     * <p>
     * 先碰107，后补：
     * {"tip_list":[{"type":5,"id":1,"opcard":[107],"weight":3,"card":107},{"type":5,"id":2,"opcard":[107],"weight":4,"card":107}]}
     * <p>
     * 手上有3个摸一个204：开补
     * {"tip_list":[{"type":4,"id":1,"opcard":[204],"weight":3,"card":204},{"type":4,"id":2,"opcard":[204],"weight":4,"card":204}]}
     * <p>
     * 手上有3个，对家打一个206：开补
     * {"tip_list":[{"type":3,"id":1,"opcard":[206],"weight":3,"card":206}]}
     */
    public String actionCard(ITObject param, TaurusClient client) {
        ITArray tipList = param.getTArray("tip_list");
        ITObject params = TObject.newInstance();
        int card = 0;
        //循环
        List<Integer> yupanhandcard = new ArrayList<>();
        yupanhandcard.addAll(changShaCardInhand);
        //进行操作之前能否下听

        List<Integer> shifoutingpai = changShaSuanFaTest.handscardshifoutingpai(changShaCardInhand, chowGroup, pongGroup, gangdepai);
        boolean beforelisten = false;//记录操作之前的下听状态
        System.out.println("shifoutingpai" + shifoutingpai);
        if (shifoutingpai.size() > 0) {
            beforelisten = true;
        }

        System.out.println("beforelisten" + beforelisten);
        //如果杠了之后还能继续听牌则杠

        //优先处理胡牌
        for (int i = 0; i < tipList.size(); i++) {
            TObject firstTip1 = (TObject) tipList.get(i).getObject();
            int type = firstTip1.getInt("type");
            int id = firstTip1.getInt("id");
            if (type == 6) {
                params.putString("session", session + "," + token);
                params.putInt("qi", 0);
                params.putInt("id", id);
                //使用延迟方法
                delayedActionCard(client, params, "胡牌");
                return "胡牌";
            }
        }

        //如果下听了，可以杠
        for (int i = 0; i < tipList.size(); i++) {
            TObject firstTip = (TObject) tipList.get(i).getObject();
            int type = firstTip.getInt("type");
            int id = firstTip.getInt("id");
            int weight = firstTip.getInt("weight");
            card = firstTip.getInt("card");


            if ((type == 5 || type == 3 || type == 4) && weight == 4) {
                //判断开杠后是否能下听
                List<Integer> gangusecars = new ArrayList<>();
                gangusecars.addAll(changShaCardInhand);

                if (type == 3) {
                    Util.removeCard(gangusecars, card, 3);
                    List<Integer> shifoutingpai3 = changShaSuanFaTest.handscardshifoutingpai(gangusecars, chowGroup, pongGroup, gangdepai);
                    System.out.println(shifoutingpai3);

                    if (shifoutingpai3.size() > 0) {
                        //开杠
                        //判断是否杠了之后没有牌可以听
                        List<Integer> allList = new ArrayList<>();
                        allList.addAll(changShaCardInhand);
                        allList.addAll(changShachuguopai);
                        int jutingnum = changShaSuanFaTest.getTingPainum(shifoutingpai3, allList);
                        if (jutingnum == 0) {
                            params.putString("session", session + "," + token);
                            params.putInt("qi", 0);
                            params.putInt("id", 0);
                            delayedActionCard(client, params, "不开杠");
                            return "不开杠";
                        }

                        Util.removeCard(changShaCardInhand, card, 3);
                        params.putString("session", session + "," + token);
                        params.putInt("qi", 0);
                        params.putInt("id", id);
                        delayedActionCard(client, params, "开杠");
                        return "开杠";
                    } else {
                        params.putString("session", session + "," + token);
                        params.putInt("qi", 0);
                        params.putInt("id", 0);
                        delayedActionCard(client, params, "不开杠");
                        return "不开杠";
                    }
                }

                if (type == 4) {


                    Util.removeCard(gangusecars, card, 4);
                    List<Integer> shifoutingpai4 = changShaSuanFaTest.handscardshifoutingpai(gangusecars, chowGroup, pongGroup, gangdepai);
                    if (shifoutingpai4.size() > 0) {
                        //开杠

                        //判断是否杠了之后没有牌可以听
                        List<Integer> allList = new ArrayList<>();
                        allList.addAll(changShaCardInhand);
                        allList.addAll(changShachuguopai);
                        int jutingnum = changShaSuanFaTest.getTingPainum(shifoutingpai4, allList);
                        if (jutingnum == 0) {
                            params.putString("session", session + "," + token);
                            params.putInt("qi", 0);
                            params.putInt("id", 0);
                            delayedActionCard(client, params, "不开杠");
                            return "不开杠";
                        }

                        Util.removeCard(changShaCardInhand, card, 4);
                        params.putString("session", session + "," + token);
                        params.putInt("qi", 0);
                        params.putInt("id", id);
                        delayedActionCard(client, params, "开杠");
                        return "开杠";
                    } else {
                        params.putString("session", session + "," + token);
                        params.putInt("qi", 0);
                        params.putInt("id", 0);
                        delayedActionCard(client, params, "不开杠");
                        return "不开杠";
                    }
                }
                if (type == 5) {

                    Util.removeCard(gangusecars, card, 1);
                    List<Integer> shifoutingpai5 = changShaSuanFaTest.handscardshifoutingpai(gangusecars, chowGroup, pongGroup, gangdepai);
                    if (shifoutingpai5.size() > 0) {
                        //开杠

                        //判断是否杠了之后没有牌可以听
                        List<Integer> allList = new ArrayList<>();
                        allList.addAll(changShaCardInhand);
                        allList.addAll(changShachuguopai);
                        int jutingnum = changShaSuanFaTest.getTingPainum(shifoutingpai5, allList);
                        if (jutingnum == 0) {
                            params.putString("session", session + "," + token);
                            params.putInt("qi", 0);
                            params.putInt("id", 0);
                            delayedActionCard(client, params, "不开杠");
                            return "不开杠";

                        }

                        Util.removeCard(changShaCardInhand, card, 1);
                        params.putString("session", session + "," + token);
                        params.putInt("qi", 0);
                        params.putInt("id", id);
                        delayedActionCard(client, params, "开杠");
                        return "开杠";
                    } else {
                        params.putString("session", session + "," + token);
                        params.putInt("qi", 0);
                        params.putInt("id", 0);
                        delayedActionCard(client, params, "不开杠");
                        return "不开杠";
                    }
                }


            }
        }

        //判断是否是大胡
        int beforeIsDahu = 0;

        beforeIsDahu = changShaSuanFaTest.checkDahu(yupanhandcard, chowGroup, pongGroup, gangdepai);
        System.out.println("bef:" + beforeIsDahu);
        //5、门清
        if (yupanhandcard.size() == 13 && beforelisten) {
            beforeIsDahu = 5;//门清
        }

        //操作之前出现的牌
        List<Integer> allSeeCard = new ArrayList<>();


        Map<Integer, ITObject> pingfenResult = new HashMap<>();
        Map<Integer, ITObject> idObject = new HashMap<>();

        for (int i = 0; i < tipList.size(); i++) {
            TObject firstTip = (TObject) tipList.get(i).getObject();
            int type = firstTip.getInt("type");
            int id = firstTip.getInt("id");
            int weight = firstTip.getInt("weight");
            card = firstTip.getInt("card");
            ITArray opcard = TArray.newInstance();
            opcard = firstTip.getTArray("opcard");
            if (type == 6) {
                params.putString("session", session + "," + token);
                params.putInt("qi", 0);
                params.putInt("id", id);
                //使用延迟动作方法
                delayedActionCard(client, params, "胡牌");
                return "胡牌";
            }
            //对应的数据
            ITObject tmp = new TObject();
            //处理听的结果
            switch (type) {
                case 1:
                    //吃
                    tmp = changShaSuanFaTest.pingguChi(beforelisten, card, opcard, yupanhandcard, beforeIsDahu, allSeeCard, chowGroup, pongGroup, gangdepai, changShachuguopai);
                    break;
                case 2:
                    //碰
                    tmp = changShaSuanFaTest.pingguPeng(beforelisten, card, opcard, yupanhandcard, beforeIsDahu, allSeeCard, chowGroup, pongGroup, gangdepai, changShachuguopai);
                    break;
                default:
                    break;
            }
            //记录下来事件
            if (tmp.size() > 0) {
                pingfenResult.put(id, tmp);
            }
            ITObject sj = new TObject();
            sj.putInt("weight", weight);
            sj.putInt("type", type);
            sj.putTArray("opcard", opcard);
            idObject.put(id, sj);
        }
        //计算分数
        System.out.println(pingfenResult);
        if (pingfenResult.size() > 0) {
            int changeid = changShaSuanFaTest.suanfen(pingfenResult);
            System.out.println("changeid:" + changeid);
            //选择最优的分数
            if (changeid == 0) {
                params.putString("session", session + "," + token);
                params.putInt("qi", 0);
                params.putInt("id", 0);
                delayedActionCard(client, params, "");
                return null;
            } else {
                //获取
                ITObject tmp = null;
                for (Map.Entry<Integer, ITObject> entry : idObject.entrySet()) {
                    if (entry.getKey() == changeid) {
                        tmp = entry.getValue();
                        System.out.println("tmp ++++++++++=  " + tmp);
                        if (tmp.getInt("type") == 2) {
                            //碰
                            ITArray outcards = tmp.getTArray("opcard");
                            for (int i = 0; i < outcards.size(); i++) {
                                Util.removeCard(changShaCardInhand, outcards.getInt(0), 2);
                            }
                            pongGroup.add(outcards.getInt(0));
                            pongGroup.add(outcards.getInt(0));
                            pongGroup.add(outcards.getInt(0));

                        } else if (tmp.getInt("type") == 1) {
                            //吃
                            ITArray outcards = tmp.getTArray("opcard");
                            for (int i = 0; i < outcards.size(); i++) {
                                Util.removeCard(changShaCardInhand, outcards.getInt(i), 1);
                            }
                            System.out.println("判断吃 +++++++++" + card);
                            System.out.println("判断吃 ==========" + outcards);
                            chowGroup.add(card);
                            chowGroup.add(outcards.getInt(0));
                            chowGroup.add(outcards.getInt(1));
                        }
                    }
                }
                params.putString("session", session + "," + token);
                params.putInt("qi", 0);
                params.putInt("id", changeid);
                //使用延迟动作方法
                String actionName = (tmp.getInt("type") == 2) ? "碰牌" : "吃牌";
                delayedActionCard(client, params, actionName);
                return null;

            }
        }

        //计算牌数

        //如果 不吃，不碰，而且差三手牌情况，则补
        for (int i = 0; i < tipList.size(); i++) {
            TObject firstTip = (TObject) tipList.get(i).getObject();
            int type = firstTip.getInt("type");
            int id = firstTip.getInt("id");
            int weight = firstTip.getInt("weight");
            card = firstTip.getInt("card");

            Map<String, Object> map = new HashMap<>();
            List<Integer> tmpChangSch = new ArrayList<>();
            tmpChangSch.addAll(yupanhandcard);
            ChangshaWinSplitCard.checkNormalHu(tmpChangSch, map);
            System.out.println("要不要补map:" + map);

            Map<String, Object> map2 = new HashMap<>();
            List<Integer> tmpChangSch2 = new ArrayList<>();
            tmpChangSch2.addAll(yupanhandcard);
            if (type == 3) {
                Util.removeCard(tmpChangSch2, card, 3);
            } else if (type == 4) {
                Util.removeCard(tmpChangSch2, card, 3);
            } else if (type == 5) {
                Util.removeCard(tmpChangSch2, card, 4);
            }

            ChangshaWinSplitCard.checkNormalHu(tmpChangSch2, map2);
            System.out.println("要不要补map2:" + map2);
            System.out.println(yupanhandcard);
            //假设补牌
            //如果下听不能不能补牌
            if (beforelisten) {
                System.out.println("b补");
                params.putString("session", session + "," + token);
                params.putInt("qi", 0);
                params.putInt("id", 0);
                delayedActionCard(client, params, "");
                return null;
            }
            //去一张下听？
            Map<Integer, List<Integer>> afterDahuOpbg = changShaSuanFaTest.quyizhangDahuTingPai(yupanhandcard, chowGroup, pongGroup, gangdepai);
            Map<Integer, List<Integer>> afterOpbg = changShaSuanFaTest.quyizhangTingPai(yupanhandcard);
            if (type == 4) {
                if (afterDahuOpbg.size() > 0 || afterOpbg.size() > 0) {
                    System.out.println("bs补");
                    params.putString("session", session + "," + token);
                    params.putInt("qi", 0);
                    params.putInt("id", 0);
                    delayedActionCard(client, params, "补牌");
                    return null;
                }
            }

            if (map.size() > 0 && weight == 3) {

                if (map2.size() > 0) {
                    //判断补牌后
                    if (Integer.parseInt(map2.get("remainingMelds").toString()) > Integer.parseInt(map.get("remainingMelds").toString()) && Integer.parseInt(map.get("remainingMelds").toString()) <= 2) {
                        System.out.println("b补");
                        params.putString("session", session + "," + token);
                        params.putInt("qi", 0);
                        params.putInt("id", 0);
                        delayedActionCard(client, params, "");
                        return null;
                    } else {

                        //判断七对
                        int dh = changShaSuanFaTest.checkDahu(yupanhandcard, chowGroup, pongGroup, gangdepai);
                        if (dh > 0) {
                            System.out.println("不补");
                            params.putString("session", session + "," + token);
                            params.putInt("qi", 0);
                            params.putInt("id", 0);
                            delayedActionCard(client, params, "不开杠");
                            return "不开杠";
                        }

                        System.out.println("补");

                        params.putString("session", session + "," + token);
                        params.putInt("qi", 0);
                        params.putInt("id", id);

                        if (type == 3) {
                            Util.removeCard(changShaCardInhand, card, 3);
                            gangdepai.add(card);
                            gangdepai.add(card);
                            gangdepai.add(card);
                            gangdepai.add(card);
                        }
                        if (type == 4) {
                            Util.removeCard(changShaCardInhand, card, 4);
                            gangdepai.add(card);
                            gangdepai.add(card);
                            gangdepai.add(card);
                            gangdepai.add(card);
                        }
                        if (type == 5) {
                            Util.removeCard(changShaCardInhand, card, 1);
                            gangdepai.add(card);
                            gangdepai.add(card);
                            gangdepai.add(card);
                            gangdepai.add(card);
                        }
                        delayedActionCard(client, params, "");
                        return null;
                    }

                } else {
                    params.putString("session", session + "," + token);
                    params.putInt("qi", 0);
                    params.putInt("id", id);

                    if (type == 3) {
                        Util.removeCard(changShaCardInhand, card, 3);
                        gangdepai.add(card);
                        gangdepai.add(card);
                        gangdepai.add(card);
                        gangdepai.add(card);
                    }
                    if (type == 4) {
                        Util.removeCard(changShaCardInhand, card, 4);
                        gangdepai.add(card);
                        gangdepai.add(card);
                        gangdepai.add(card);
                        gangdepai.add(card);
                    }
                    if (type == 5) {
                        Util.removeCard(changShaCardInhand, card, 1);
                        gangdepai.add(card);
                        gangdepai.add(card);
                        gangdepai.add(card);
                        gangdepai.add(card);
                    }
                    delayedActionCard(client, params, "补牌");
                    return null;
                }
            }
        }
        System.out.println("actchangShaCardInhand"+changShaCardInhand);
        params.putString("session", session + "," + token);
        params.putInt("qi", 0);
        params.putInt("id", 0);
        delayedActionCard(client, params, "默认动作");

        return null;
    }


    public static String changePlayer(String command, Message message) {
        if (command.equalsIgnoreCase("820")) {
            ITObject param = message.param;
            if (param == null) {
                return null;
            }

        }
        return null;
    }


    /**
     * 出牌方法
     */
    public String outCard(TaurusClient client, Map<Integer, List<Integer>> playerOutcardsMap, Map<Integer, List<Integer>> playerchisMap, Map<Integer,
            List<Integer>> playerpengsMap, Map<Integer, List<Integer>> playermingsMap, Map<Integer, List<Integer>> playerzisMap) {
        // playerOutcardsMap + playerchisMap 传到 outCardSuanFa
        //对出牌进行整合
        try {


            List<Integer> resultList = new ArrayList<>();
            for (List<Integer> cards : playerOutcardsMap.values()) {
                resultList.addAll(cards);
            }

            for (List<Integer> chis : playerchisMap.values()) {
                resultList.addAll(chis);
            }

            for (List<Integer> pengs : playerpengsMap.values()) {
                resultList.addAll(pengs);
            }

            for (List<Integer> minggangs : playermingsMap.values()) {
                resultList.addAll(minggangs);
            }

            for (List<Integer> zigang : playerzisMap.values()) {
                resultList.addAll(zigang);
            }

            System.out.println("长沙麻将出牌" + changShaCardInhand);
            // 长沙麻将出牌
            String changShaOutCard = changShaSuanFaTest.outCardSuanFa(changShaCardInhand, pongGroup, chowGroup, gangdepai, resultList);
            System.out.println("长沙麻将出牌" + changShaCardInhand);

            ITObject params = TObject.newInstance();
            int cardToOut;
            if (StringUtil.isNotEmpty(changShaOutCard)) {
                cardToOut = Integer.parseInt(changShaOutCard);
            } else {
                cardToOut = changShaCardInhand.get(0);
            }

            params.putInt("card", cardToOut);
            int outCountBefore = changShachuguopai.size(); // 当前历史出牌数量

            // 第n次出牌时，发送前n-1张出牌
            if (outCountBefore >= 1) {
                // 发送前n-1张（所有历史出牌）
                List<Integer> cardsToSend = changShachuguopai.subList(0, outCountBefore);
                params.putTArray("outcard_list", CardUtil.maJiangToTArray(cardsToSend));
            }
            params.putTArray("card_list", CardUtil.maJiangToTArray(changShaCardInhand));

            // 将当前出的牌添加到历史出牌列表
            changShachuguopai.add(cardToOut);
            System.out.println("changShachuguopai ++++ :" + changShachuguopai);
            // 从手牌中移除
            changShaCardInhand.remove(Integer.valueOf(cardToOut));
            System.out.println("打过后的手牌 +++ " + changShaCardInhand);
            params.putString("session", session + "," + token);

            //使用线程池替代CompletableFuture.runAsync + Thread.sleep
            getBusinessThreadPool().execute(() -> {
                try {
                    int ot = new Random().nextInt(4);
                    Thread.sleep(ot*1000);
                    client.send("611", params, response -> {

                    });
                } catch (Exception e) {
                    System.out.println("Thread error");
                }
            });


        }catch (Exception e){

        }

        return null;
    }

    /**
     * 删除出过的牌组
     *
     * @param param
     * @return
     */
    public String shanchuchuguopai(ITObject param) {
        System.out.println("对面吃碰删除出过的牌组");
        if (param == null) {
            return null;
        }

        Integer card = param.getInt("card"); // 操作牌值
        Integer type = param.getInt("type"); // 操作类型


        Integer playerid = param.getInt("playerid");


        //Redis中获取机器人ID列表
        List<Integer> robotIdsList = new ArrayList<>();

        //Redis中获取当前活跃的机器人连接信息
        Jedis jedis = Redis.use("group1_db2").getJedis();
        try {
            //从Redis中获取所有在线的机器人ID
            Set<String> allKeys = jedis.keys("{robot}:*");
            for (String key : allKeys) {
                robotIdsList.add(Integer.valueOf(key.replace("{robot}:","")));
            }
        } finally {
            jedis.close();
        }

        if (!robotIdsList.contains(playerid)) {
            System.out.println("playerid  "+playerid);
            System.out.println("type  "+type);
            if (type == 2 || type == 3 || type == 5 || type == 1) { // 碰，杠
                System.out.println("进入对面吃牌 机器人出的牌需要删除这张牌");
                getChuGuoCardInhand().remove(Integer.valueOf(card));
            }
        }

        return null;
    }
}
