package hunan;

import com.game.Util;
import com.taurus.core.entity.ITArray;
import com.taurus.core.entity.ITObject;
import com.taurus.core.entity.TObject;
import com.taurus.core.plugin.database.DataBase;
import com.taurus.core.util.StringUtil;
import taurus.client.Message;
import taurus.client.TaurusClient;
import taurus.util.CardUtil;
import taurus.util.ChangShaSuanFaTest;

import java.sql.SQLException;
import java.util.*;

public class HuNanChangSha {


    public static int changShaCard = 0;

    //湖南红中麻将手牌
    private List<Integer> changShaCardInhand = new ArrayList<>();

    private List<Integer> changShaCardInhandgang = new ArrayList<>();


    //红中麻将出过的牌
    private List<Integer> changShachuguopai = new ArrayList<>();


    private List<Integer> gangdepai = new ArrayList<>();


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


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


    // 玩家座位号
    public static int seat = 0;

    public static int playerId = 0;


    // 会话标识
    public static String session = "";
    // 访问令牌
    public static String token = "";
    //红中麻将算法
//    private static HongZhongSuanFa hongZhongSuanFa = new HongZhongSuanFa();

    private static ChangShaSuanFaTest changShaSuanFaTest = new ChangShaSuanFaTest();


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

    public List<Integer> getgangdepai() {
        return gangdepai;
    }

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

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

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

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


    /**
     * 出牌广播协议 812
     *
     * @param command 协议号
     * @param message 消息对象
     * @return
     */
    public static String drawCard(String command, Message message) {
        if (command.equalsIgnoreCase("812")) {
            ITObject param = message.param;
            if (param == null) {
                return null;
            }
            changShaCard = param.getInt("card");
            System.out.println("出牌广播" + changShaCard);
            System.out.println("座位号:" + param.getInt("seat") + "的用户出牌:" + param.getInt("card"));
        }
        return null;
    }


    /**
     * 摸牌协议 819
     *
     * @param command 协议号
     * @param message 消息对象
     * @return
     */
    public String getCard(String command, Message message) {
        System.out.println("摸牌协议-----" + command + "message---" + message);
        if (command.equalsIgnoreCase("819")) {
            ITObject param = message.param;
            if (param == null) {
                return null;
            }

            System.out.println("轮到用户:" + param.getInt("player") + "的用户摸牌" + ",牌为：" + param.getInt("card"));
            System.out.println("用户id" + playerId);
            System.out.println("座位号" + param.getInt("seat"));
            if (param.getInt("player") != null) {
                int drawnCard = param.getInt("card");

                changShaSuanFaTest.drawnCards = drawnCard;//存储摸到的牌
                changShaCardInhand.add(drawnCard);
                System.out.println("摸牌后手牌" + changShaCardInhand);

                changShaSuanFaTest.analyzeHand(changShaCardInhand);


            }
        }
        return null;
    }

    /**
     * 判断是否应该碰牌
     *
     * @param proposedCard 提议碰的牌
     * @return 是否应该碰牌
     */
    public boolean shouldPong(int proposedCard) {
        System.out.println("判断是否应该碰牌: " + proposedCard);

        // 直接调用hongZhongSuanFaTest中的shouldPong方法，它已经包含了所有需要的规则
        return changShaSuanFaTest.shouldPong(proposedCard, changShaCardInhand);

//        return hongZhongSuanFaTest.shouldPong(proposedCard, Arrays.asList(305,304,303,207,207,204,204,208,208,201,201,412,412));
    }


    public boolean shouldChow(int proposedCard) {
        System.out.println("判断是否应该吃牌: " + proposedCard);
        return changShaSuanFaTest.shouldChow(proposedCard, changShaCardInhand);
    }

    /**
     * 初始化手牌协议 811
     *
     * @param command 协议号
     * @param message 消息对象
     * @return
     */
    public String cardInHead(String command, Message message, TaurusClient client) {
        if (command.equalsIgnoreCase("811")) {
            ITObject param = message.param;
            if (param == null) {
                return null;
            }
//            {bank_seat=1, laiziCard=0, laiziCard2=0, laiziCard2Before=0, jing=0, laiziCardBefore=0, card_list=[101, 103, 104, 201, 204, 207, 208, 209, 307, 309, 501, 502, 503]}
            ITArray cardList = param.getTArray("card_list");
            for (int i = 0; i < cardList.size(); i++) {
                changShaCardInhand.add(cardList.getInt(i));
            }
//            if (changShaCardInhand.size() > 13) {
//                outCard(client);
//                System.out.println("机器人:" + param.getInt("seat") + "为庄家，需要出牌" + ",牌为：" + changShaCardInhand.get(0));
//            }
            System.out.println("机器人:" + param.getInt("seat") + "初始化手牌" + ",牌为：" + changShaCardInhand.toString());

        }
        return null;
    }

    /**
     * 处理杠碰胡操作
     *
     * @param param 消息参数
     * @return
     */
    public String actionCard(ITObject param, TaurusClient client) {
        //获取碰杠胡参数 type  和id 后续算法接入，是否能让碰和杠
        ITArray tipList = param.getTArray("tip_list");
        int id = 0;
        int type = 0;
        int opcard = 0;
        int opcard1 = 0;
        int card = 0;

        //胡牌
        ITObject params = TObject.newInstance();
        for (int i = 0; i < tipList.size(); i++) {
            TObject firstTip = (TObject) tipList.get(i).getObject();
            id = firstTip.getInt("id");
            type = firstTip.getInt("type");

            System.out.println("id ++ " + id);
            System.out.println("type ++ " + type);
            ITArray opcard2 = firstTip.getTArray("opcard");
            System.out.println("opcard2" + opcard2);
            if (type == 6) {
                params.putString("session", session + "," + token);
                params.putInt("qi", 0);
                params.putInt("id", id);
                client.send("612", params, response -> {
                    System.out.println("操作成功: " + response.returnCode);
                });
                System.out.println("执行胡牌");
                return "胡牌";
            }
        }

        //吃杠
        int type2 = 0;
        int opcard3 = 0;
        int id3 = 0;

        for (int i = 0; i < tipList.size(); i++) {
            TObject firstTip = (TObject) tipList.get(i).getObject();
            type2 = firstTip.getInt("type");
            opcard3 = firstTip.getTArray("opcard").getInt(0);
            id3 = firstTip.getInt("id");

            if (type2 == 3) {
                int pisCardsCount = changShaSuanFaTest.countPairs(changShaCardInhand);
                boolean gang = isAllSameSuitgang(changShaCardInhand, opcard3);
                if (pisCardsCount < 5 && gang) {
                    params.putString("session", session + "," + token);
                    params.putInt("qi", 0);
                    params.putInt("id", id3);
                    Util.removeCard(changShaCardInhand, opcard3, 3);
                    System.out.println("执行吃杠");
                    client.send("612", params, response -> {
                        System.out.println("操作成功: " + response.returnCode);
                    });
                    return "吃杠";
                } else {
                    params.putString("session", session + "," + token);
                    params.putInt("qi", 0);
                    params.putInt("id", 0);
                    client.send("612", params, response -> {
                        System.out.println("操作成功: " + response.returnCode);
                    });
                    System.out.println("根据规则，决定不吃杠: " + opcard3);
                }
            }
        }


        int id1 = 0;
        int type1 = 0;

        if (tipList.size() > 0) {
            TObject firstTip = (TObject) tipList.get(0).getObject();
            id1 = firstTip.getInt("id");
            type1 = firstTip.getInt("type");

            System.out.println("id1 ++ " + id1);
            System.out.println("type1 ++ " + type1);
            ITArray opcard2 = firstTip.getTArray("opcard");
            System.out.println("opcard2" + opcard2);
            card = firstTip.getInt("card");

            opcard = firstTip.getTArray("opcard").getInt(0);
            if (type1 == 1) {
                opcard1 = firstTip.getTArray("opcard").getInt(1);
            }
        }


        if (type1 == 2) {
            ChangShaSuanFaTest changShaSuanFaTest = new ChangShaSuanFaTest();
            int pisCardsCount = changShaSuanFaTest.countPairs(changShaCardInhand);//分析七小对
            boolean peng = changShaSuanFaTest.isAllSameSuit1(changShaCardInhand);
            // 根据规则判断是否应该碰牌
            if (shouldPong(opcard) && pisCardsCount < 5 && !peng) {
                params.putString("session", session + "," + token);
                params.putInt("qi", 0);
                params.putInt("id", id1);
                pongGroup.add(opcard);
                pongGroup.add(opcard);
                pongGroup.add(opcard);
                Util.removeCard(changShaCardInhand, opcard, 2);
                System.out.println("执行碰牌并删除碰的牌");
            } else {
                params.putString("session", session + "," + token);
                params.putInt("qi", 1); // 放弃碰牌
                params.putInt("id", 0);
                System.out.println("根据规则，决定不碰牌: " + opcard);
            }
        } else if (type1 == 3) {
            int pisCardsCount = changShaSuanFaTest.countPairs(changShaCardInhand);//分析七小对
            boolean gang = changShaSuanFaTest.isAllSameSuit1(changShaCardInhand);
            if (pisCardsCount < 5 && !gang) {
                params.putString("session", session + "," + token);
                params.putInt("qi", 0);
                params.putInt("id", id1);
                Util.removeCard(changShaCardInhand, opcard, 3);
                System.out.println("执行吃杠");
            } else {
                params.putString("session", session + "," + token);
                params.putInt("qi", 0);
                params.putInt("id", 0);
                System.out.println("根据规则，决定不吃杠: " + opcard);
            }

        } else if (type1 == 1) {
            System.out.println("长度------" + String.valueOf(opcard).length());
            int pisCardsCount = changShaSuanFaTest.countPairs(changShaCardInhand);//分析七小对
            boolean isChow = changShaSuanFaTest.isAllSameSuit1(changShaCardInhand);
            if (shouldChow(card) && pisCardsCount < 5 && !isChow) {
                System.out.println("决定吃---" + opcard);
                params.putString("session", session + "," + token);
                params.putInt("qi", 0);
                params.putInt("id", 1);

                System.out.println("----card----" + card);
                System.out.println("----opcard----" + opcard);
                System.out.println("----opcard1----" + opcard1);


                chowGroup.add(card);
                chowGroup.add(opcard);
                chowGroup.add(opcard1);
//                changShachuguopai.add(card);
                Util.removeCard(changShaCardInhand, opcard, 1);
                Util.removeCard(changShaCardInhand, opcard1, 1);
            } else {
                params.putString("session", session + "," + token);
                params.putInt("qi", 1);
                params.putInt("id", 0);
                System.out.println("根据规则，决定不吃: " + opcard);
            }

            //自杠
        } else if (type1 == 4) {
            int pisCardsCount = changShaSuanFaTest.countPairs(changShaCardInhand);//分析七小对
            boolean gang = changShaSuanFaTest.isAllSameSuit1(changShaCardInhand);
            if (pisCardsCount < 5 && !gang) {
                params.putString("session", session + "," + token);
                params.putInt("qi", 0);
                params.putInt("id", 1);
                Util.removeCard(changShaCardInhand, opcard, 4);
                System.out.println("执行自杠");
            } else {
                params.putString("session", session + "," + token);
                params.putInt("qi", 0);
                params.putInt("id", 0);
            }

            // 碰后补杠
        } else if (type1 == 5) {
            params.putString("session", session + "," + token);
            params.putInt("qi", 0);
            params.putInt("id", 1);
            Util.removeCard(changShaCardInhand, opcard, 1);
            System.out.println("执行碰后补杠");
        }

        client.send("612", params, response -> {
            System.out.println("操作成功: " + response.returnCode);
        });
        return null;
    }


    public static boolean isAllSameSuitgang(List<Integer> handCards, int opcard3) {
        // 统计各花色的牌数量
        Map<Integer, Integer> suitCountMap = new HashMap<>();

        for (Integer card : handCards) {
            int suit = card / 100; // 获取花色，100=万，200=筒，300=条
            suitCountMap.put(suit, suitCountMap.getOrDefault(suit, 0) + 1);
        }

        // 检查是否有花色的牌数量超过8张
        for (Map.Entry<Integer, Integer> entry : suitCountMap.entrySet()) {
            int suit = entry.getKey();
            int count = entry.getValue();
            if (count >= 9) {
                // 检查杠牌的花色是否与当前花色一致
                int gangSuit = opcard3 / 100;
                if (suit == gangSuit) {
                    return true;
                } else {
                    return false;
                }
            }
        }
        return true;
    }

    public static String changePlayer(String command, Message message) {
        if (command.equalsIgnoreCase("820")) {
            ITObject param = message.param;
            if (param == null) {
                return null;
            }
            System.out.println("出牌权转移到座位号:" + param.getInt("seat") + "的用户");
        }
        return null;
    }


    /**
     * 出牌方法
     */
//    public  String outCard(TaurusClient client, List<Integer> list) {
    public String outCard(TaurusClient client) {

        // 红中麻将出牌
        String changShaOutCard = changShaSuanFaTest.outCardSuanFa(changShaCardInhand, changShaCard, pongGroup, chowGroup);
//        String changShaOutCard = changShaSuanFaTest.outCardSuanFa(list, changShaCard,pongGroup);
        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));
        System.out.println("机器人牌============" + params);
        // 将当前出的牌添加到历史出牌列表
        changShachuguopai.add(cardToOut);
        // 从手牌中移除
        changShaCardInhand.remove(Integer.valueOf(cardToOut));
        System.out.println("出牌: " + cardToOut);
        System.out.println("目前机器人剩余手牌：" + changShaCardInhand.toString());
        params.putString("session", session + "," + token);
        client.send("611", params, response -> {
            System.out.println("出牌成功: " + response.returnCode);
        });
        return null;
    }

    /**
     * 删除出过的牌组
     *
     * @param param
     * @return
     */
    public String shanchuchuguopai(ITObject param) {
        if (param == null) {
            return null;
        }
        Integer card = param.getInt("card"); // 操作牌值
        Integer type = param.getInt("type"); // 操作类型
        Integer from_seat = param.getInt("from_seat"); // 牌来源座位
        System.out.println("删除出过的牌组 card  " + card);
        System.out.println("删除出过的牌组 type  " + type);
        System.out.println("删除出过的牌组 from_seat  " + from_seat);
        System.out.println("机器人 seat  " + seat);
        Integer playerid = param.getInt("playerid");
        System.out.println("playerid +++++" + playerid);

        String sql2 = String.format("SELECT id FROM `account` WHERE jiqiren=9998");
        try {
            ITArray robotId2 = DataBase.use().executeQueryByTArray(sql2);
            List<Integer> robotIdsList = new ArrayList<>();

            for (int j = 0; j < robotId2.size(); j++) {
                robotIdsList.add(robotId2.getTObject(j).getInt("id"));
            }

            if (!robotIdsList.contains(playerid)) {
                if (type == 2 || type == 3 || type == 5 || type == 1) { // 碰，杠
                    getChuGuoCardInhand().remove(Integer.valueOf(card));
                    System.out.println("删除出过的牌组 成功");
                }
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }

        return null;
    }
}
