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

namespace GameFix.Poker
{
    public class CardStyle123Helper : CardStyleBaseHelper
    {
        public override int CardStyle => DataCardConst.CardStyle123;
        public override int CardCnt => 5;
        
        internal override bool CheckStyleNormal(CardBaseGroup group, out CardStyleInfo cardStyleInfo)
        {
            cardStyleInfo = null;
            if (group.Cards.Count >= CardCnt)
            {
                if (IsContinuous(group.CardGroupList, 1, out var shunCnt) 
                    && shunCnt.Count == 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)
            {
                if (IsAllSame(group.NoLZCards)) return false; // 直接组成炸弹

                if (IsMaxContinuousByLZ(group.CardGroupList, 1, group.LZCards.Count,
                        out var shunValueList, out var lackValueList))
                {
                    if (shunValueList.Count == group.Cards.Count)
                    {
                        cardStyleInfo = new CardStyleInfo(CardStyle, shunValueList[0], shunValueList.Count);
                        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 == 0)
                        break;
                    
                    continuousList.Add(group.CardGroupList[i + j].First());

                    if (continuousList.Count >= 5)
                    {
                        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> lackValues = new List<int>();
            int needCnt = 0;
            for (int i = minValue; i < MaxShunLogicNum; i++)
            {
                if (group.CardGroupList[i].Count > 0)
                {
                    continuousList.Add(group.CardGroupList[i].First());
                }
                else
                {
                    needCnt++;
                    lackValues.Add(i);
                }
                bool isBreak = group.CardGroupList[i].Count < 1 && 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)
                {
                    lackValues.Clear();
                    continuousList.Clear();
                    needCnt = 0;
                }
            }
            
            return groupList;
        }
    }
}