using GameData;
using MrWu.Debug;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GameFix.Poker;
using GameFix.PaoDeKuaiF;
using GameMessage;
using GameMessage.PaoDeKuaiF;

namespace PdkFriendServer.Logic
{
    public partial class PdkGameMain
    {
        /// <summary>
        /// 获取黑桃3的位置，如果都没有黑桃3那就取黑桃4
        /// </summary>
        /// <returns></returns>
        byte GetHeiTao3Pos()
        {
            byte result = 0;
            for (byte carId = 3; carId < 14; carId++)
            {//从黑桃3开始找，没有找到就依次往上查找
                for (byte i = 0; i < GamePack.Info.PlayNum; i++)
                {
                    for (int j = GamePack.CardPack.Cards[i].CardInfos.Length - 1; j >= 0; j--)
                    {
                        if (GamePack.CardPack.Cards[i].CardInfos[j].Flower != 1) continue;
                        if (GamePack.CardPack.Cards[i].CardInfos[j].GameNum > carId) break;
                        if (GamePack.CardPack.Cards[i].CardInfos[j].GameNum == carId)
                        {
                            result = (byte)(i + 1);
                            return result;
                        }
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 获取红桃十的玩家位置
        /// </summary>
        /// <returns>0没有玩家有红桃十 大于0就是改位置的玩家</returns>
        byte GetHongTaoShiPos()
        {
            byte result = 0;
            for (byte i = 0; i < GamePack.Info.PlayNum; i++)
            {
                for (int j = GamePack.CardPack.Cards[i].CardInfos.Length - 1; j >= 0; j--)
                {
                    if (GamePack.CardPack.Cards[i].CardInfos[j].Flower != 2) continue;
                    if (GamePack.CardPack.Cards[i].CardInfos[j].GameNum == 10)
                    {
                        result = (byte)(i + 1);
                        return result;
                    }
                }
            }

            return 0;
        }

        /// <summary>
        /// 查找下一个玩家的位置
        /// </summary>
        /// <param name="pos"></param>
        /// <returns></returns>
        byte GetNextPos(byte pos)
        {
            if (pos <= 0) throw new Exception("参数错误" + pos);
            byte result = (byte)(pos + 1);
            if (result > GamePack.Info.PlayNum)
            {
                result = 1;
            }
            return result;
        }

        /// <summary>
        /// 游戏是否结束
        /// </summary>
        /// <returns>true游戏结束 false游戏没有结束</returns>
        bool IsGameOver(byte chupaoPos)
        {
            if (GamePack.Info.BaoPos > 0 && GamePack.Info.ShenYuCard[GamePack.Info.BaoPos - 1] == 0)
            {
                //包庄人的牌出完了，游戏结束
                GamePack.Info.OverPos = GamePack.Info.BaoPos;
                return true;
            }

            //如果是包庄的话，出牌的人
            if (GamePack.Info.BaoPos > 0 && chupaoPos > 0)
            {
                var b = GamePack.Info.BaoPos != chupaoPos; //如果出牌的位置和包庄位置不一样。就说明被别人给压牌了，游戏结束
                if (b)
                {
                    GamePack.Info.OverPos = chupaoPos; //记录压他牌的人位置
                }
                return b;
            }

            for (int i = 0; i < GamePack.Info.PlayNum; i++)
            {
                if (GamePack.Info.ShenYuCard[i] <= 0)
                { //只要有一个玩家的牌出完就结束
                    GamePack.Info.OverPos = (byte)(i + 1);
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 检查出牌包内容
        /// </summary>
        /// <param name="pack"></param>
        /// <returns></returns>
        public bool CheckChuPai(PlayOutCardPdkF payCard)
        {
            if (payCard.Pos <= 0 || payCard.Pos > 3) return false;
            if (PokerLogic.CheckSameId(payCard.Ids))
            {
                Log($"玩家出了相同ID的牌型，{payCard}", DebugLevel.Error);
                return false;
            }
            if (GamePack.Info.MaxPlayCard.GameNum == 0 && payCard.Type == CardType1.None) return false; //第一个出牌人不能出不要
            if (GamePack.Info.MaxPlayCard.GameNum > 0 && payCard.Type == CardType1.None)
            {
                if (!Rule.BiYa && !Rule.XiaJiaBaoDan) return true; //不是必压的情况下,并且没有勾选下家报单，之前有人出牌，再出个不要可以出
                //不必压，但是勾选下家报单，之前出的不是单张，这个时候可以出不要。
                if (!Rule.BiYa && Rule.XiaJiaBaoDan && GamePack.Info.MaxPlayCard.Type != CardType1.DanZhang) return true;
                if (!Rule.BiYa && Rule.XiaJiaBaoDan && GamePack.Info.ShenYuCard[GetNextPos(payCard.Pos) - 1] != 1) return true;
            }
            if (!CheckPaiIsInHand(payCard.Ids, payCard.Pos)) return false;
            if (!Rule.AAAIsZhaDan && payCard.Type == CardType1.ZhaDan && payCard.GameNum == 14) return false; //3个A不是炸弹
            if (!Rule.SiDai2 && payCard.Type == CardType1.SiDai2) return false;
            if (!Rule.SiDai3 && payCard.Type == CardType1.SiDai3) return false;
            //if (!Rule.BiYa && GamePack.Info.MaxPlayCard.GameNum > 0 && payCard.Type == CardType.None) return true; //如果之前有人出牌，再出个不要可以出
            if ((Rule.BiYa ||
                (Rule.XiaJiaBaoDan && GamePack.Info.MaxPlayCard.Type == CardType1.DanZhang && GamePack.Info.ShenYuCard[GetNextPos(payCard.Pos) - 1] == 1))
                && payCard.Type == CardType1.None)
            { //如果是必压，玩家出了不要，检查一下玩家有没有必上一家大的牌               
                return !PdkCardAlgorithm.CheckHaveBigger(GamePack.Info.MaxPlayCard, GamePack.CardPack.Cards[payCard.Pos - 1].CardInfos.Where(x => x.GameState == 1).ToArray(),
                    GamePack.CardPack.Cards[GamePack.Info.MaxPlayCard.Pos - 1].CardInfos, Rule.AAAIsZhaDan);
            }
            int count = GamePack.Info.ShenYuCard[payCard.Pos - 1];
            //单张、对子、三带二、顺子、连对、飞机带翅膀、炸弹，四带三、四带二
            if (payCard.Type == CardType1.SanDai2 && count >= 5 && payCard.Ids.Length < 5) return false;
            if (payCard.Type == CardType1.SiDai3 && count >= 7 && payCard.Ids.Length < 7) return false;
            if (payCard.Type == CardType1.SiDai2 && count >= 6 && payCard.Ids.Length < 6) return false;
            if (payCard.Type == CardType1.FeiJi)
            {//如果飞机的张数不够就返回false
                if (count >= 10 && payCard.Ids.Length < 10) return false;
                var sanzhang = PokerLogic.GetFeiJiCount(GetCardByIds(payCard.Pos, payCard.Ids));
                var c = sanzhang * 3 + sanzhang * 2;
                if (count >= c && payCard.Ids.Length < c) return false;
                var maxSanZahng = PokerLogic.GetFeiJiCount(GetCardByIds(GamePack.Info.MaxPlayCard.Pos, GamePack.Info.MaxPlayCard.Ids));
                if (sanzhang < maxSanZahng) return false;
            }
            if (GamePack.Info.MaxPlayCard.GameNum == 0)
            {
                //如果最大的出牌人是没有值的话，然后当前人不是出不要就可以出下去。
                return payCard.Type != CardType1.None;
            }
            if (GamePack.Info.MaxPlayCard.Type == payCard.Type)
            {
                if (payCard.Type == CardType1.DanZhang || payCard.Type == CardType1.DuiZi || payCard.Type == CardType1.ShunZi || payCard.Type == CardType1.LianDui)
                {
                    return payCard.Ids.Length == GamePack.Info.MaxPlayCard.Ids.Length && payCard.GameNum > GamePack.Info.MaxPlayCard.GameNum;
                }
                else
                {
                    return payCard.GameNum > GamePack.Info.MaxPlayCard.GameNum;
                }

            }
            else
            {
                if (GamePack.Info.MaxPlayCard.Type != CardType1.ZhaDan)
                {
                    return payCard.Type == CardType1.ZhaDan;
                }
            }
            return false;
        }

        /// <summary>
        /// 检测牌是否都在玩家手上
        /// </summary>
        /// <param name="Ids">要检测的牌ID集合</param>
        /// <param name="pos">要检测哪个玩家的手牌</param>
        /// <returns>true都在手上 false没有在手上</returns>
        bool CheckPaiIsInHand(byte[] Ids, int pos)
        {
            if (pos <= 0 || pos > GamePack.Info.PlayNum) return false;
            if (Ids == null || Ids.Length <= 0) return true; //没有牌不检测
            pos--;
            int count = 0;
            foreach (var id in Ids)
            {
                foreach (var item in GamePack.CardPack.Cards[pos].CardInfos)
                {
                    if (item.ID == id && item.GameState == 1)
                    {
                        count++;
                        break;
                    }
                }
            }
            return count == Ids.Length;
        }

        /// <summary>
        /// 给某个玩家加炸弹，其他玩家减炸弹
        /// </summary>
        /// <param name="pos"></param>
        /// <param name="num"></param>
        void AddZhaDanCount(int pos, int num)
        {
            for (int i = 0; i < GamePack.Info.ZhaDans.Length; i++)
            {
                if (i + 1 == pos)
                {
                    GamePack.Info.ZhaDans[i] += num * (GamePack.Info.ZhaDans.Length - 1);
                }
                else
                {
                    GamePack.Info.ZhaDans[i] -= num;
                }
            }
        }

        /// <summary>
        /// 设置朋友房规则
        /// </summary>
        public void SetFriendGz()
        {
            if (this.DeskGameDo == null) return;
            var gz = this.DeskGameDo.GetRoomGz();
            Rule = new PdkRule();
            Rule.BiYa = true;//不必压
            if (gz[0] == '0')
            {
                Rule.JingDianWanFa = true;
            }
            else if (gz[0] == '1')
            {
                Rule.Zhang15 = true;
            }
            else if (gz[0] == '2')
            {
                Rule.GuanPai = true;
                Rule.BiYa = false;//不必压
            }
            if (gz[1] == '0')
            {
                Rule.ShouJu3 = true;
            }
            else if (gz[1] == '1')
            {
                Rule.MeiJu3 = true;
            }
            if (gz[2] == '0')
            {
                Rule.SiDai3 = true;
            }
            else if (gz[2] == '1')
            {
                Rule.SiDai2 = true;
            }
            if (gz[8] == '0')
            {
                GamePack.Info.PlayNum = 2;
            }
            else if (gz[8] == '1')
            {
                GamePack.Info.PlayNum = 3;
            }
            Rule.XianShenYuPai = gz[3] == '1';
            Rule.HongTao10ZhaNiao = gz[4] == '1';
            Rule.BaoZhuang = gz[5] == '1';
            Rule.AAAIsZhaDan = gz[6] == '1';
            Rule.XiaJiaBaoDan = gz[7] == '1';
            Rule.ZhaDanDeFen = gz[9] == '1';
            Rule.HeiTao3BiChu = gz[11] == '1';
            switch (gz[10]) //设置托管
            {
                case '0':
                    Rule.TuoGuanNum = 0;
                    break;
                case '1':
                    Rule.TuoGuanNum = 1;
                    break;
                case '2':
                    Rule.TuoGuanNum = 3;
                    break;
                case '3':
                    Rule.TuoGuanNum = 5;
                    break;
            }
        }

        /// <summary>
        /// 闹钟计时器
        /// </summary>
        public int TimeNum = 0;

        /// <summary>
        /// 包庄托管
        /// </summary>
        void BaoZhuangTuoGuan()
        {
            //  var seat = GamePack.Info.WhoPlay - 1;
            int count = 0;
            for (int i = 0; i < GamePack.Info.PlayNum; i++)
            {
                var pl = this.DeskGameDo.desk[i];
                if (pl != null && pl.isDePosit)
                {
                    count++;
                }
            }
            if (count == 0) return; //不需要托管
            //GamePack.Info.PlayTuoGauan[seat] = 1;
            for (byte i = 0; i < GamePack.Info.PlayNum; i++)
            {
                var pl = this.DeskGameDo.desk[i];
                if (GamePack.Info.BaoZhuang[i] == 0 && pl != null && pl.isDePosit)
                {
                    GamePack.Info.BaoZhuang[i] = 2;
                }
            }
            Debug.Info("包庄托管!GameDo");
            GameDo();
        }

        /// <summary>
        /// 返回黑桃三的下标
        /// </summary>
        /// <param name="cards">可以出的牌组合</param>
        /// <param name="index">返回黑桃三的下标</param>
        /// <returns>false没有黑桃三 true有黑桃三</returns>
        bool GetHei3Index(List<List<TCardInfoPdkF>> cards, out int index)
        {
            index = -1;
            try
            {

                if (cards == null || cards.Count <= 0) return false;
                bool isfirstChu = GamePack.Info.PlayNum == 2 ? GamePack.Info.ShenYuCard[0] == GamePack.Info.ShenYuCard[1]
                   : GamePack.Info.ShenYuCard[0] == GamePack.Info.ShenYuCard[1] && GamePack.Info.ShenYuCard[1] == GamePack.Info.ShenYuCard[2];
                if (!isfirstChu) return false; //如果不是第一次出牌， 就不管
                for (int i = 0; i < cards.Count; i++)
                {
                    if (cards[i] == null || cards[i].Count <= 0) continue;
                    if (cards[i][0].Flower == 1 && cards[i][0].GameNum == 3)
                    {
                        index = i;
                        return true;
                    }
                }
                return false;
            }
            catch (Exception e)
            {
                Debug.Error($"返回黑桃三的下标 msg:{e.Message},code:{e.StackTrace}");
            }
            return false;
        }

        /// <summary>
        /// 打牌托管
        /// </summary>
        void DaPaiTuoGuan()
        {
            var seat = GamePack.Info.WhoPlay - 1;
            var pl = this.DeskGameDo.desk[seat];
            if (pl == null) return; //不需要托管
            if (Rule.BiYa)
            {
                if (pl.outline == 0)
                {//玩家没有离线
                    if (!pl.isDePosit) return; //不需要托管
                }
                else
                {//玩家离线
                    if (!pl.isDePosit && GamePack.Info.MaxPlayCard.GameNum <= 0) return;
                }
            }
            else
            {
                if (!pl.isDePosit) return; //不需要托管
            }
            //GamePack.Info.PlayTuoGauan[seat] = 1; //加这个是为了兼容老客户端
            if (GamePack.Info.MaxPlayCard.GameNum <= 0)
            { //托管先出
                var tishi = PdkCardAlgorithm.GetTipCard(GamePack.Info.MaxPlayCard,
                    GamePack.CardPack.Cards[GamePack.Info.WhoPlay - 1].CardInfos.Where(x => x.GameState == 1).ToArray(),
                    GamePack.Info.MaxPlayCard.Pos == 0 ? null : GamePack.CardPack.Cards[GamePack.Info.MaxPlayCard.Pos - 1].CardInfos,
                    Rule.AAAIsZhaDan);
                var idx = Rule.XiaJiaBaoDan && GamePack.Info.ShenYuCard[GetNextPos(GamePack.Info.WhoPlay) - 1] == 1 ? tishi.Count - 1 : 0;
                if (Rule.HeiTao3BiChu && logicMemory.WarCount == 0)
                {//如果首局黑桃三首次必出，第一次出牌就必出黑桃三
                    var h3 = GetHei3Index(tishi, out var idx3);
                    if (h3 && idx3 >= 0)
                    {
                        idx = idx3;
                    }
                }
                var payCard = new PlayOutCardPdkF();
                payCard.Pos = (byte)GamePack.Info.WhoPlay;
                payCard.Type = CardType1.DanZhang;
                payCard.GameNum = tishi[idx][0].GameNum;
                payCard.Ids = tishi[idx].Select(x => x.ID).ToArray();
                Log($"who:{GamePack.Info.WhoPlay}先出 ,托管出的牌：{payCard}");
                GamePack.Info.ActivePlayCard = payCard;
            }
            else
            {
                var shoupai = GamePack.CardPack.Cards[GamePack.Info.WhoPlay - 1].CardInfos.Where(x => x.GameState == 1).ToArray();
                var tishi = PdkCardAlgorithm.GetTipCard(GamePack.Info.MaxPlayCard,
                   shoupai,
                    GamePack.Info.MaxPlayCard.Pos == 0 ? null : GamePack.CardPack.Cards[GamePack.Info.MaxPlayCard.Pos - 1].CardInfos,
                    Rule.AAAIsZhaDan, true);
                var payCard = new PlayOutCardPdkF();
                payCard.Pos = (byte)GamePack.Info.WhoPlay;
                if (tishi == null || tishi.Count <= 0)
                {
                    payCard.Type = CardType1.None;
                }
                else
                {
                    if (pl.outline == 1 && !pl.isDePosit) return; //玩家离线并且没有到托管时间
                    payCard.Type = PdkCardAlgorithm.IsZhaDan(tishi[tishi.Count - 1].ToArray(), Rule.AAAIsZhaDan) ? CardType1.ZhaDan : GamePack.Info.MaxPlayCard.Type;
                    var idx = Rule.XiaJiaBaoDan && GamePack.Info.ShenYuCard[GetNextPos(GamePack.Info.WhoPlay) - 1] == 1 && payCard.Type == CardType1.DanZhang ? 0 : tishi.Count - 1;
                    payCard.GameNum = tishi[idx][0].GameNum;
                    payCard.Ids = tishi[idx].Select(x => x.ID).ToArray();
                    if (payCard.Type == CardType1.FeiJi || payCard.Type == CardType1.SanDai2)
                    {
                        int n = (payCard.Ids.Length / 3) * 2;
                        var chaCard = shoupai.Except(tishi[idx]);
                        List<TCardInfoPdkF> chupais = new List<TCardInfoPdkF>(16);
                        chupais.AddRange(tishi[idx]);
                        chupais.AddRange(chaCard.Reverse().Take(n));
                        payCard.Ids = chupais.Select(x => x.ID).ToArray();
                    }
                }
                Log($"who:{GamePack.Info.WhoPlay}跟牌 pai:{GamePack.Info.MaxPlayCard}托管出的牌：{payCard}");
                GamePack.Info.ActivePlayCard = payCard;
            }
            Debug.Info("打牌托管GameDo!");
            GameDo();
        }

        /// <summary>
        /// 游戏临时加载的初始化
        /// </summary>
        public void LoadInit()
        {
            logicMemory.Init();
            TimeNum = 0;
        }
    }
}
