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

namespace GameFix.Poker
{
    /// <summary>
    /// 手牌组
    /// 有些逻辑需要校验手牌，用这个组
    /// 目前不包含癞子逻辑得判断
    /// </summary>
    public class CardHandGroup : CardBaseGroup
    {
        public CardBaseGroup CheckCardGroup { get; private set;}
        
        public CardHandGroup(IEnumerable<Card> cards, Deck deck) : base(cards, deck)
        {
        }
        
        /// <summary>
        /// 拆解部分牌组
        /// </summary>
        public List<CardGroupList> DecomposePart(List<int> styles)
        {
            List<CardGroupList> ret = new List<CardGroupList>();
            var cardGroup = mDeck.CreateCardGroup(mCards);
            foreach (var helper in mCardStyleBaseHelpers)
            {
                if (!styles.Contains(helper.CardStyle)) continue;
                
                var styleCards = helper.GetAllStyleCards(cardGroup, false);
                foreach (var cardList in styleCards)
                {
                    if (cardList.CardStyleInfo == null)
                        cardList.CardStyleInfo = GetCardStyleInfo(cardList);
                }
                ret.AddRange(styleCards);
                cardGroup.RemoveCards(styleCards);
            }
            
            return ret;
        }

        /// <summary>
        /// 拆解牌组
        /// </summary>
        public List<CardGroupList> Decompose()
        {
            List<CardGroupList> ret = new List<CardGroupList>();
            var cardGroup = mDeck.CreateCardGroup(mCards);
            foreach (var helper in mCardStyleBaseHelpers)
            {
                var styleCards = helper.GetAllStyleCards(cardGroup, false);
                foreach (var cardList in styleCards)
                {
                    if (cardList.CardStyleInfo == null)
                        cardList.CardStyleInfo = GetCardStyleInfo(cardList);
                }
                ret.AddRange(styleCards);
                cardGroup.RemoveCards(styleCards);
            }

            if (cardGroup.Cards.Count > 0)
            { // 还有未知牌型没有拆解完？ （理论不存在）
                ret.Add(new CardGroupList(cardGroup.Cards));
            }
            
            return ret;
        }
        
        public List<CardGroupList> GetShunTip(CardStyleInfo targetStyle, byte[] tipHelpers)
        {
            List<CardGroupList> ret = new List<CardGroupList>();
            for (int i = 0; i < tipHelpers.Length; i++)
            {
                var helper = GetHelper(tipHelpers[i]);
                var tipCardList = helper?.GetAllEatTipGroup(this, targetStyle);
                if (tipCardList != null && tipCardList.Count > 0)
                {
                    ret.AddRange(tipCardList.OrderByDescending(x=>x.Count));
                    return ret;
                }
            }
            
            return ret;
        }
        
        public List<CardGroupList> GetEatTip(int styleId)
        {
            List<CardGroupList> ret = new List<CardGroupList>();
            var helper = GetHelper(styleId);
            if (helper != null)
            {
                ret.AddRange(helper.GetAllEatTipGroup(this, null));

                if (ret.Count == 0 && mLZCards.Count > 0)
                {
                    ret.AddRange(helper.GetAllEatTipGroupWithLZ(this, null));
                }
            }

            return ret;
        }
        
        /// <summary>
        /// 获取吃牌提示
        /// </summary>
        public List<CardGroupList> GetEatTip(CardStyleInfo targetStyle)
        {
            List<CardGroupList> ret = new List<CardGroupList>();
            if (targetStyle == null)
            {
                // 没有提供对方牌型，先判断自己手牌是否符合一种牌型可以一次性出完
                var styleInfo = GetCardStyleInfo(mCards);
                bool isCanOutImmediate = false;
                if (styleInfo.CardStyle !=  DataCardConst.CardStyle0)
                {
                    var cardGroupList = new CardGroupList(mCards);
                    cardGroupList.CardStyleInfo = styleInfo;
                    ret.Add(cardGroupList);
                    isCanOutImmediate = true;
                }

                if (!isCanOutImmediate)
                {
                    foreach (var helper in mCardStyleBaseHelpers)
                    {
                        ret.AddRange(helper.GetAllEatTipGroup(this, null));
                    }
                }
            }
            else
            {
                foreach (var helper in mCardStyleBaseHelpers)
                {
                    if (mStyleComparer.Greater(helper.CardStyle, targetStyle.CardStyle))
                    {
                        ret.AddRange(helper.GetAllEatTipGroup(this, targetStyle));
                    }
                }
            }

            // 牌类型赋值
            var filterRet = new List<CardGroupList>();
            foreach (var cardList in ret)
            {
                if (cardList.Count == 0) continue;
                if (cardList.CardStyleInfo == null)
                    cardList.CardStyleInfo = GetCardStyleInfo(cardList);
                if (mStyleComparer.Greater(cardList.CardStyleInfo, targetStyle))
                {
                    filterRet.Add(cardList);
                }
            }

            return filterRet;
        }
                
        /// <summary>
        /// 获取cards符合条件牌型
        /// </summary>
        public CardStyleInfo GetCardStyleInfo(IEnumerable<Card> cards)
        {
            CheckCardGroup = mDeck.CreateCardGroup(cards);
            foreach (var helper in mCardStyleBaseHelpers)
            {
                if (helper.CheckStyleNormal(this, out var chekStyleInfo))
                {
                    return chekStyleInfo;
                }
            }

            CheckCardGroup = null;
            CardStyleInfo cardStyleInfo = new CardStyleInfo();
            cardStyleInfo.CardStyle = DataCardConst.CardStyle0;   
            return cardStyleInfo;
        }
                
        /// <summary>
        /// 获取cards符合条件牌型
        /// </summary>
        public List<CardStyleInfo> GetCardStyleInfos(IEnumerable<Card> cards)
        {
            CheckCardGroup = mDeck.CreateCardGroup(cards);
            List<CardStyleInfo> cardStyleInfos = new List<CardStyleInfo>();
            foreach (var helper in mCardStyleBaseHelpers)
            {
                if (helper.CheckStyleNormal(this, out var chekStyleInfo))
                {
                    cardStyleInfos.Add(chekStyleInfo);
                }
            }
            CheckCardGroup = null;
            return cardStyleInfos;
        }
                
        /// <summary>
        /// 检测cards牌型是否符合条件
        /// </summary>
        public bool CheckCardStyleInfoValidate(IEnumerable<Card> cards, CardStyleInfo cardStyleInfo, out CardStyleInfo chkStyleInfo)
        {
            chkStyleInfo = new CardStyleInfo();
            CheckCardGroup = mDeck.CreateCardGroup(cards);
            foreach (var helper in mCardStyleBaseHelpers)
            {
                if (helper.CardStyle == cardStyleInfo.CardStyle)
                {
                    // 先检测是否符合普通牌型
                    if (helper.CheckStyleNormal(this, out chkStyleInfo))
                    {
                        return true;
                    }
                }
            }

            return false;
        }
    }
}