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

namespace GameFix.Poker
{
    public class CardStyle112233Helper : CardStyleBaseHelper
    {
        public override int CardStyle => DataCardConst.CardStyle112233;
        public override int CardCnt => 6;
        
        internal override bool CheckStyleNormal(CardBaseGroup group, out CardStyleInfo cardStyleInfo)
        {
            cardStyleInfo = null;
            if (group.Cards.Count >= CardCnt && group.Cards.Count % 2 == 0)
            {
                if (IsContinuous(group.CardGroupList, 2, out var shunCnt) 
                    && shunCnt.Count * 2 == group.Cards.Count)
                {
                    cardStyleInfo = CardStyleHelper.CreateCardStyleInfo(CardStyle, group.Cards);
                    return true;
                }
            }
            return false;
        }

        internal override bool CheckStyleWithLZ(CardBaseGroup group, out CardStyleInfo cardStyleInfo)
        {
            cardStyleInfo = null;
            if (group.Cards.Count >= CardCnt && group.Cards.Count % 2 == 0)
            {
                if (IsAllSame(group.NoLZCards)) return false;

                if (IsMaxContinuousByLZ(group.CardGroupList, 2, group.LZCards.Count,
                        out var shunValueList, out var lackValueList))
                {
                    if (shunValueList.Count * 2 == group.Cards.Count)
                    {
                        cardStyleInfo = new CardStyleInfo(CardStyle, shunValueList[0], shunValueList.Count * 2);
                        cardStyleInfo.CardLackValues = lackValueList.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 minValue = eatStyleInfo != null ? eatStyleInfo.CardValue + 1 : 3;
            var continuousCnt = eatStyleInfo?.CardCnt ?? -1;
            List<Card> continuousList = new List<Card>();
            for (int i = minValue; i < group.CardGroupList.Count; i++)
            {
                continuousList.Clear();
                for (int j = 0; j < group.CardGroupList.Count; j++)
                {
                    if (i + j >= group.CardGroupList.Count)
                        break;
                    if (group.CardGroupList[i + j].Count <= 1)
                        break;
                    
                    continuousList.AddRange(group.CardGroupList[i + j].GetRange(0, 2));

                    if (continuousList.Count >= CardCnt && continuousList.Count % 2 == 0)
                    {
                        if (continuousCnt == -1 || continuousCnt == continuousList.Count)
                        {
                            groupList.Add(new CardGroupList(continuousList));
                        }
                    }
                }
            }

            return groupList;
        }

        internal override List<CardGroupList> GetAllEatTipGroupWithLZ(CardBaseGroup group, CardStyleInfo eatStyleInfo)
        {
            var minValue = eatStyleInfo != null ? eatStyleInfo.CardValue + 1 : 3;
            var continuousCnt = eatStyleInfo?.CardCnt ?? -1;
            var groupList = new List<CardGroupList>();
            List<Card> continuousList = new List<Card>();
            List<int> lackValueList = new List<int>();
            int needCnt = 0;
            for (int i = minValue; i < group.CardGroupList.Count; i++)
            {
                var count = group.CardGroupList[i].Count;
                if (count >= 2)
                {
                    continuousList.AddRange(group.CardGroupList[i].GetRange(0, 2));
                }
                else
                {
                    needCnt += (2 - count);
                    lackValueList.AddRange(Enumerable.Repeat(i, (2 - count)));
                }
                bool isBreak = group.CardGroupList[i].Count < 2 && needCnt > group.LZCards.Count;

                if (continuousList.Count + needCnt >= CardCnt && needCnt <= group.LZCards.Count)
                {
                    if (continuousCnt == -1 || continuousCnt == continuousList.Count + needCnt)
                    {
                        continuousList.AddRange(group.LZCards.GetRange(0, needCnt));
                        groupList.Add(new CardGroupList(continuousList));
                        break;
                    }
                } else if (isBreak)
                {
                    continuousList.Clear();
                    needCnt = 0;
                }
            }
            
            return groupList;
        }
    }
}