using System.Collections.Generic;
using System.Linq;
using GameMessage;

namespace GameFix.Poker
{
    public class CardStyle32Helper : CardStyleBaseHelper
    {
        public override int CardStyle => DataCardConst.CardStyle32;
        public override int CardCnt => 5;
        
        internal override bool CheckStyleNormal(CardBaseGroup group, out CardStyleInfo cardStyleInfo)
        {
            cardStyleInfo = null;
            if (group.Cards.Count == CardCnt)
            {
                int mainValue = 0, withValue = 0;
                for (int i = 0; i < group.CardGroupList.Count; i++)
                {
                    if (group.CardGroupList[i].Count == 3)
                    {
                        mainValue = i;
                    }
                    
                    if (group.CardGroupList[i].Count == 2)
                    {
                        withValue = i;
                    }
                }

                if (mainValue > 0 && withValue > 0)
                {
                    cardStyleInfo = new CardStyleInfo(CardStyle, mainValue, group.Cards.Count);
                    return true;
                }
            }
            return false;
        }

        internal override bool CheckStyleWithLZ(CardBaseGroup group, out CardStyleInfo cardStyleInfo)
        {
            cardStyleInfo = null;
            if (group.Cards.Count == CardCnt)
            {
                if (IsAllSame(group.NoLZCards)) return false; // 直接组成炸弹

                int lzCount = group.LZCards.Count;
                int threeCV = 0, pairCV = 0;
                List<int> lackValues = new List<int>(group.LZCards.Count);
                for (int i = group.CardGroupList.Count - 1; i >= 0; i--)
                {
                    int cardV = i;
                    int count = group.CardGroupList[i].Count;
                    if (count == 0) continue;
                    int needCnt = 0;
                    if ((3 - count) <= lzCount)
                    {
                        // 找到三张相同的牌
                        needCnt = 3 - count;
                        threeCV = cardV;
                    }
                    else if ((2 - count) <= lzCount)
                    {
                        // 找到两张相同的牌
                        needCnt = 2 - count;
                        pairCV = cardV;
                    }
                    lzCount -= needCnt;
                    lackValues.AddRange(Enumerable.Repeat(cardV, needCnt));
                }

                if (threeCV != 0 && pairCV != 0 && lzCount == 0)
                {
                    cardStyleInfo = new CardStyleInfo(CardStyle, threeCV, CardCnt);
                    cardStyleInfo.CardLackValues = lackValues.ToArray();
                    return true;
                }
            }
            return false;
        }

        internal override List<CardGroupList> GetAllEatTipGroup(CardBaseGroup group, CardStyleInfo eatStyleInfo)
        {
            var groupCnt = group.CardGroupList.Count;
            var groupList = new List<CardGroupList>(groupCnt);
            var sortGroupList = group.CardGroupList.OrderBy((x) => x.Count).ToList();
            for (int i = 0; i < groupCnt; i++)
            {
                var cardGroup = group.CardGroupList[i];
                if (cardGroup.Count == 3 && IsSameGroupGreater(cardGroup, eatStyleInfo))
                {
                    // 从其他组中找一对
                    for (int j = 0; j < groupCnt; j++)
                    {
                        if (sortGroupList[j] != cardGroup && sortGroupList[j].Count >= 2)
                        {
                            var newCardGroup = new CardGroupList(cardGroup);
                            newCardGroup.AddRange(sortGroupList[j].GetRange(0, 2));
                            groupList.Add(newCardGroup);
                        }
                    }
                }
            }

            return groupList;
        }

        internal override List<CardGroupList> GetAllEatTipGroupWithLZ(CardBaseGroup group, CardStyleInfo eatStyleInfo)
        {
            var cardGroupList = group.CardGroupDic.Where(kv => kv.Key >= 1)
                .SelectMany(kv => kv.Value).OrderByDescending(x=>x.Count).ToList();
            var groupList = new List<CardGroupList>();
            foreach (var cardGroup in cardGroupList)
            {
                if (cardGroup.Count > 0 
                    && cardGroup.First().Value > eatStyleInfo.CardValue
                    && !IsJoker(cardGroup))
                {
                    var needCnt = CardCnt - cardGroup.Count - 2;
                    if (needCnt <= group.LZCards.Count)
                    {
                        List<Card> tmpList = new List<Card>();
                        tmpList.AddRange(cardGroup);
                        
                        // 获取一个对子，不够用癞子补充
                        for (int i = cardGroupList.Count - 1; i >= 0; i--)
                        {
                            if (cardGroupList[i] != cardGroup && !IsJoker(cardGroupList[i]))
                            {
                                if (cardGroupList[i].Count >= 2)
                                {
                                    tmpList.AddRange(cardGroupList[i].GetRange(0, 2));
                                    break;
                                }
                                else if (2 - cardGroupList[i].Count <= group.LZCards.Count - needCnt)
                                {
                                    tmpList.AddRange(cardGroupList[i]);
                                    needCnt += (2 - cardGroupList[i].Count);
                                    break;
                                }
                            }
                        }

                        tmpList.AddRange(group.LZCards.GetRange(0, needCnt));
                        if (tmpList.Count == CardCnt)
                        {
                            groupList.Add(new CardGroupList(tmpList));
                        }
                    }
                }
            }

            return groupList;
        }
    }
}