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

namespace GameFix.Poker
{
    public abstract class CardStyleBaseHelper
    {
        public virtual int CardStyle => DataCardConst.CardStyle0; 
        public virtual int CardCnt => 0;

        protected readonly int MaxShunLogicNum = 14; // 顺子所能到达得最大值
        
        // 检测普通牌型
        internal abstract bool CheckStyleNormal(CardBaseGroup group, out CardStyleInfo cardStyleInfo);
        
        // 检测癞子牌型 (有癞子的检测方法)
        internal virtual bool CheckStyleWithLZ(CardBaseGroup group, out CardStyleInfo cardStyleInfo)
        {
            return CheckStyleNormal(group, out cardStyleInfo);
        }
        
        // 获取group中所有符合牌型的组合
        internal abstract List<CardGroupList> GetAllEatTipGroup(CardBaseGroup group, CardStyleInfo eatStyleInfo);
        
        // 获取group中所有符合牌型的组合(带癞子的手牌)
        internal virtual List<CardGroupList> GetAllEatTipGroupWithLZ(CardBaseGroup group, CardStyleInfo eatStyleInfo)
        {
            return GetAllEatTipGroup(group, eatStyleInfo);
        }
        
        /// <summary>
        /// 获取所有符合条件得牌型
        /// </summary>
        internal virtual List<CardGroupList> GetAllStyleCards(CardBaseGroup group, bool isSplitCard) { return new List<CardGroupList>(); }
        
        // 是否都相同
        protected bool IsAllSame(List<Card> cards)
        {
            if (cards.Count == 0) return false;
            if (cards.Count == 1) return true;
            
            for (int i = 1; i < cards.Count; i++)
            {
                if (cards[i].Value != cards[i-1].Value)
                {
                    return false;
                }
            }

            return true;
        }
        
        /// <summary>
        /// 是否连续
        /// </summary>
        protected bool IsContinuous(List<int> continuousValues)
        {
            if (continuousValues.Count == 1) return false;
            continuousValues.Sort();
            for (int i = 1; i < continuousValues.Count; i++)
            {
                if (continuousValues[i] - continuousValues[i-1] != 1)
                {
                    return false;
                }
            }

            return true;
        }
        
        // 是否连续
        protected bool  IsContinuous(List<CardGroupList> cardValueCnt, int sameCnt, out List<int> shunValueList)
        {
            shunValueList = new List<int>();
            for (int i = 0; i < cardValueCnt.Count; i++)
            {
                //顺子中断
                if (cardValueCnt[i].Count < 1 && shunValueList.Count > 0)
                    break;
                
                if (cardValueCnt[i].Count > sameCnt)
                    break;
                    
                if (cardValueCnt[i].Count == sameCnt)
                {
                    shunValueList.Add(i);
                }
            }

            return shunValueList.Count > 0;
        }
        
        // 是否最大的连续
        protected bool IsMaxContinuous(List<CardGroupList> cardValueCnt, int sameCnt, out List<int> shunValueList)
        {
            List<int> maxShunValueList = new List<int>();
            shunValueList = new List<int>();
            for (int i = 0; i < cardValueCnt.Count; i++)
            {
                if (cardValueCnt[i].Count >= sameCnt)
                {
                    shunValueList.Add(i);
                }
                else if(shunValueList.Count >= maxShunValueList.Count)
                {
                    maxShunValueList.Clear();
                    maxShunValueList.AddRange(shunValueList);
                    shunValueList.Clear();
                }
            }

            if (maxShunValueList.Count > shunValueList.Count)
            {
                shunValueList.Clear();
                shunValueList.AddRange(maxShunValueList);
            }

            return shunValueList.Count > 0;
        }

        /// <summary>
        /// 判断带癞子的最大连顺
        /// </summary>
        protected bool IsMaxContinuousByLZ(List<CardGroupList> cardValueCnt, int sameCnt, int lzCount, 
            out List<int> shunValueList, out List<int> lackValueList)
        {
            shunValueList = new List<int>();
            lackValueList = new List<int>(lzCount);
            List<int> maxShunCards = new List<int>();
            List<int> maxLackValues = new List<int>(lzCount);
            int tmpLzCount = lzCount;
            for (int i = 0; i <= MaxShunLogicNum; i++)
            {
                int count = cardValueCnt[i].Count;
                int needCnt = sameCnt - count;
                if (cardValueCnt[i].Count == sameCnt)
                {
                    shunValueList.Add(i);
                } else if (needCnt <= tmpLzCount 
                           && needCnt >= 0 
                           && (shunValueList.Count > 0 || count > 0))
                { // 用癞子补充
                    tmpLzCount -= needCnt;
                    shunValueList.Add(i);
                    lackValueList.AddRange(Enumerable.Repeat(i, needCnt));
                }
                else 
                { // 中断（记录这一次得连顺）
                    if (shunValueList.Count > maxShunCards.Count)
                    {
                        maxShunCards.Clear();
                        maxShunCards.AddRange(shunValueList);
                        maxLackValues.Clear();
                        maxLackValues.AddRange(lackValueList);
                    }
                    // 重置癞子
                    tmpLzCount = lzCount;
                    shunValueList.Clear();
                    lackValueList.Clear();
                }
            }
            
            if (maxShunCards.Count > shunValueList.Count)
            {
                shunValueList.Clear();
                shunValueList.AddRange(maxShunCards);
                lackValueList.Clear();
                lackValueList.AddRange(maxLackValues);
            }

            shunValueList.Sort();
            return shunValueList.Count > 0;
        }

        // 相同牌组的值是否更大
        protected bool IsSameGroupGreater(CardGroupList group, CardStyleInfo eatStyleInfo)
        {
            if (group.Count == 0) return false;

            if (eatStyleInfo != null && CardStyle == eatStyleInfo.CardStyle)
                return group[0].Value > eatStyleInfo.CardValue;

            return true;
        }

        protected bool IsJoker(CardGroupList group)
        {
            return IsContainJoker(group);
        }
        
        protected bool IsContainJoker(List<Card> cards)
        {
            for (int i = 0; i < cards.Count(); i++)
            {
                if (DataCardConst.JokerValues.Contains(cards[i].Value))
                    return true;
            }
            return false;
        }
    }
}