using ObjectModel.Tool;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GameFix.Poker;
using GameMessage.PaoDeKuaiF;
using GameFix.PaoDeKuaiF;

namespace PdkFriendServer.Logic
{

    public partial class PdkGameMain
    {
        /// <summary>
        /// 随机值
        /// </summary>
        public readonly Random Random = new Random(unchecked((int)DateTime.UtcNow.Ticks));

        /// <summary>
        /// 发牌
        /// </summary>
        public void InitCard()
        {
            /*1、经典玩法(必压)、--经典玩法（16张玩法）：一副牌，去掉大小王、三个2（保留黑桃2）和黑桃 A ，共48张，每人16张
	15张玩法(必压)、--15张玩法（有大必压）：一副牌，去掉大小王、三个2（保留黑桃2）和三个A（保留黑桃 A ），去掉一个K，共45张，每人15张
	关牌(不必压)  --一副牌，去掉大小王、三个2（保留黑桃2）和黑桃 A ，共48张，每人16张*/
            byte count = 0;//每个人分多少张牌
            int del2 = 3; //删除2的张数
            int delA = 1;//删除A的张数
            int delK = 3;//删除K的张数
            TCardInfoPdkF[] allCards = null; //初始化牌库
            if (Rule.JingDianWanFa || Rule.GuanPai)
            {
                count = 16;
                delK = 0;
                allCards = new TCardInfoPdkF[48];
            }
            if (Rule.Zhang15)
            {
                delA = 3;
                delK = 1;
                count = 15;
                allCards = new TCardInfoPdkF[45];
            }
            int idx = 0;
            for (byte i = 1; i <= 52; i++)
            {
                PukeTool.ConvertCard(i, out var flower, out var num);
                if (del2 > 0 && num == 2 && flower != 1)
                {
                    del2--;
                    continue;
                }
                if (delA > 0 && num == 1 && flower != 1)
                {
                    delA--;
                    continue;
                }
                if (delK > 0 && num == 13 && flower != 1)
                {
                    delK--;
                    continue;
                }
                allCards[idx].ID = i;
                allCards[idx].Flower = (byte)flower;
                allCards[idx].Num = (byte)num;
                allCards[idx].GameNum = (byte)(num == 1 ? 14 : num == 2 ? 16 : num);
                allCards[idx].GameOwer = 0;
                allCards[idx].Score = 0;
                allCards[idx].GameState = 1;
                idx++;
            }
            for (byte i = 1; i < GamePack.Info.PlayNum; i++)
            {
                PukeTool.ShuffleArray(ref allCards, Random);
            }
            idx = 0;
            //给玩家发牌
            int hei3Wei = -1;//黑桃三发牌的位置            
            if (logicMemory.WarCount == 0 && Rule.HeiTao3BiChu)
            {//如果是首局而且是每局黑桃三必出，则第一局必须要发黑桃三
                hei3Wei = Random.Next(0, GamePack.Info.PlayNum);
            }
            if (hei3Wei >= 0)
            { //要发黑桃3
                List<TCardInfoPdkF> cards = allCards.ToList();
                for (int i = 0; i < GamePack.Info.PlayNum; i++)
                {
                    GamePack.CardPack.Cards[i].Init(count);
                    int j = 0;
                    while (j < count)
                    {
                        if (j == 0 && i == hei3Wei)
                        {
                            TCardInfoPdkF temp = cards.Find(x => x.GameNum == 3 && x.Flower == 1);
                            if (temp.ID > 0)
                            {
                                this.GamePack.CardPack.Cards[i].CardInfos[j] = temp;
                                cards.Remove(temp);
                            }
                            else
                            { //如果没有找到，说明黑桃3已经被别人拿走了，就不找了。
                                this.GamePack.CardPack.Cards[i].CardInfos[j] = cards[0];
                                cards.RemoveAt(0);
                            }
                        }
                        else
                        {
                            this.GamePack.CardPack.Cards[i].CardInfos[j] = cards[0];
                            cards.RemoveAt(0);
                        }
                        j++;
                    }
                    GamePack.Info.ShenYuCard[i] = count;
                }
            }
            else
            { //以前写法
                for (int i = 0; i < GamePack.Info.PlayNum; i++)
                {
                    GamePack.CardPack.Cards[i].Init(count);
                    for (int j = 0; j < count; j++)
                    {
                        this.GamePack.CardPack.Cards[i].CardInfos[j] = allCards[idx++];
                    }
                    GamePack.Info.ShenYuCard[i] = count;
                }
            }
            for (int i = 0; i < GamePack.Info.PlayNum; i++)
            {
                SortWanJiaPaiByGameNum(i + 1);
#if DEBUG
                if (this.DeskGameDo == null)
                {
                    Log($"-------------{(i + 1)}开始-----------------------------");
                    for (int j = 0; j < this.GamePack.CardPack.Cards[i].CardInfos.Length; j++)
                    {
                        Log(this.GamePack.CardPack.Cards[i].CardInfos[j].ToString());
                    }
                }
#endif
            }
        }

        /// <summary>
        /// 排序某个玩家手牌，按游戏中的大小排序
        /// </summary>
        /// <param name="pos">玩家位置从1开始</param>
        void SortWanJiaPaiByGameNum(int pos)
        {
            if (pos <= 0 || pos > GamePack.Info.PlayNum) throw new Exception($"参数错误 pos:{pos}");
            pos--;
            Array.Sort(this.GamePack.CardPack.Cards[pos].CardInfos, (x, y) => (y.GameNum * 10 - y.Flower).CompareTo((x.GameNum * 10 - x.Flower)));
        }

        /// <summary>
        /// 设置玩家出牌
        /// </summary>
        /// <param name="pos"></param>
        /// <param name="ids"></param>
        void SetCardToOut(int pos, byte[] ids)
        {
            if (ids == null || ids.Length <= 0) return;
            if (pos <= 0 || pos > GamePack.Info.PlayNum) throw new Exception($"参数错误 pos:{pos}");
            pos--;
            GamePack.Info.ShenYuCard[pos] = (byte)(GamePack.Info.ShenYuCard[pos] - ids.Length);
            foreach (var id in ids)
            {
                for (int i = 0; i < this.GamePack.CardPack.Cards[pos].CardInfos.Length; i++)
                {
                    if (this.GamePack.CardPack.Cards[pos].CardInfos[i].ID == id)
                    {
                        this.GamePack.CardPack.Cards[pos].CardInfos[i].GameState = 0;
                        break;
                    }
                }
            }
#if DEBUG
            Log($"---------------------{(pos + 1)}----- shengyu:{GamePack.Info.ShenYuCard[pos]}-------------");
            //for (int i = 0; i < this.GamePack.CardPack.Cards[pos].CardInfos.Length; i++)
            //{
            //    if (this.GamePack.CardPack.Cards[pos].CardInfos[i].GameState == 0) continue;
            //    Log(this.GamePack.CardPack.Cards[pos].CardInfos[i].ToString());
            //}
#endif
        }



        /// <summary>
        /// 根据牌的绝对Id返回牌的详细信息
        /// </summary>
        /// <param name="pos">玩家位置从1开始</param>
        /// <param name="ids">牌的Id集合</param>
        /// <returns></returns>
        TCardInfoPdkF[] GetCardByIds(int pos, byte[] ids)
        {
            if (ids == null || ids.Length <= 0) return null;
            if (pos <= 0 || pos > GamePack.Info.PlayNum) return null;
            pos--;
            return PokerLogic.GetCardByIds(GamePack.CardPack.Cards[pos].CardInfos, ids);
        }

        /// <summary>
        /// 计算玩家炸弹个数
        /// </summary>
        /// <param name="pos">玩家位置，从0开始</param>
        /// <returns></returns>
        byte CalcPlayBombRule(int pos)
        {
            if (pos < 0 || pos >= GamePack.Info.PlayNum) return 0;
            Dictionary<int, int> dic = new Dictionary<int, int>();
            foreach (var item in GamePack.CardPack.Cards[pos].CardInfos)
            {
                if (dic.ContainsKey(item.GameNum))
                {
                    dic[item.GameNum]++;
                }
                else
                {
                    dic[item.GameNum] = 1;
                }
            }
            byte result = 0;
            foreach (var item in dic)
            {
                if (item.Value <= 2) continue;
                if (Rule.AAAIsZhaDan && item.Key == 14 && item.Value == 3)
                {
                    result++;
                    continue;
                }
                if (item.Value == 4)
                {
                    result++;
                }
            }
            return result;
        }

        /// <summary>
        /// 检测玩家的飞机，如果有4连以上的飞机就需要换牌
        /// </summary>
        /// <param name="pos"></param>
        /// <returns></returns>
        void CheckFeiJi()
        {
            try
            {
                int pos = -1; //有4连飞机的位置
                List<int> feiji = null;
                for (int j = 0; j < GamePack.Info.PlayNum; j++)
                {
                    feiji = GetFeiJiCount(GamePack.CardPack.Cards[j].CardInfos);
                    if (feiji != null && feiji.Count > 3)
                    {
                        pos = j;
                        Log($"飞机数量：{string.Join(",", feiji)},飞机位置:{pos + 1},房号：{this.DeskGameDo.desk.deskinfo.roomNum}", MrWu.Debug.DebugLevel.Warning);
                        break;
                    }
                }
                if (pos < 0) return;
                for (int i = 0; i < GamePack.Info.PlayNum; i++)
                {
                    if (i != pos)
                    {
                        int idx = -1;
                        for (int j = 0; j < GamePack.CardPack.Cards[pos].CardInfos.Length; j++)
                        {
                            if (GamePack.CardPack.Cards[pos].CardInfos[j].GameNum == feiji[2])
                            {
                                idx = j;
                                break;
                            }
                        }
                        if (idx < 0)
                        {
                            Log($"没有找到4连飞机的下标日：{idx}", MrWu.Debug.DebugLevel.Warning);
                            return;
                        }
                        for (int i3 = 0; i3 < GamePack.CardPack.Cards[i].CardInfos.Length - 1; i3++)
                        {
                            //交换其中一张牌
                            TCardInfoPdkF temp = GamePack.CardPack.Cards[i].CardInfos[i3];
                            if (feiji.IndexOf(temp.GameNum) >= 0) continue; //换的牌不能是飞机的牌，要不容易重复和换出新的炸弹
                            Log($"换牌信息：{temp.GameNum}", MrWu.Debug.DebugLevel.Warning);
                            GamePack.CardPack.Cards[i].CardInfos[i3] = GamePack.CardPack.Cards[pos].CardInfos[idx];
                            GamePack.CardPack.Cards[pos].CardInfos[idx] = temp;
                            for (int i2 = 0; i2 < GamePack.Info.PlayNum; i2++)
                            {
                                SortWanJiaPaiByGameNum(i2 + 1);
                            }
                            return;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Log($"CheckFeiJi msg:{e.Message}, code:{e.StackTrace}", MrWu.Debug.DebugLevel.Error);
            }
        }

        /// <summary>
        /// 获取一个玩家的飞机牌型
        /// </summary>
        /// <param name="selectCards">玩家手里的牌</param>
        /// <returns>玩家的飞机集合</returns>
        public static List<int> GetFeiJiCount(TCardInfoPdkF[] selectCards)
        {
            if (selectCards == null || selectCards.Length < 6) return null;
            List<PokerLogic.XY> list = new List<PokerLogic.XY>();
            foreach (var item in selectCards)
            {
                var t = list.Find(x => x.x == item.GameNum);
                if (t != null)
                {
                    t.y++;
                }
                else
                {
                    list.Add(new PokerLogic.XY { x = item.GameNum, y = 1 });
                }
            }
            int num = list.Count(x => x.y >= 3);
            if (num < 2) return null;
            list = list.Where(x => x.y >= 3).ToList();
            List<int> fj = new List<int>();
            for (int i = 0; i < list.Count - 1; i++)
            {
                if (list[i].x - 1 == list[i + 1].x)
                {
                    if (!fj.Contains(list[i].x))
                    {
                        fj.Add(list[i].x);
                    }
                    if (!fj.Contains(list[i + 1].x))
                    {
                        fj.Add(list[i + 1].x);
                    }
                }
            }
            return fj;
        }
    }
}
