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

namespace GameFix.Poker
{
    /// <summary>
    /// 带王炸弹 （四张以上）
    /// </summary>
    public class CardStyleJokerBombHelper : CardStyleBombHelper
    {
        public override int CardStyle => DataCardConst.CardStyleJokerBomb;
        public override int CardCnt => 4;
        
        private bool isAllJoker = true; // 是否可以组成全王炸弹

        public CardStyleJokerBombHelper()
        {
        }
        
        public CardStyleJokerBombHelper(bool allJoker)
        {
            isAllJoker = allJoker;
        }

        internal override bool CheckStyleNormal(CardBaseGroup group, out CardStyleInfo cardStyleInfo)
        {
            cardStyleInfo = null;
            if (group.Cards.Count >= CardCnt)
            {
                // 先排除王
                var bombCards = group.Cards.Where(x=>!DataCardConst.JokerValues.Contains(x.Value)).ToList();
                // 判断是否都是王
                if (isAllJoker && bombCards.Count == 0)
                {
                    cardStyleInfo = new CardStyleInfo(CardStyle, DataCardConst.JokerValues[0], group.Cards.Count);
                    return true;
                }
                
                if (IsAllSame(bombCards) && bombCards.Count >= CardCnt)
                {
                    cardStyleInfo = new CardStyleInfo(CardStyle, bombCards.First().Value, group.Cards.Count);
                    return true;
                }
            }
            
            return false;
        }

        internal override bool CheckStyleWithLZ(CardBaseGroup group, out CardStyleInfo cardStyleInfo)
        {
            cardStyleInfo = null;
            if (group.Cards.Count < CardCnt) return false;
            if (group.LZCards.Count == group.Cards.Count && IsAllSame(group.LZCards))
            {
                cardStyleInfo = CardStyleHelper.CreateCardStyleInfo(CardStyle, group.LZCards);
                return true;
            }
            
            // 先排除王
            var bombCards = group.NoLZCards.Where(x=>!DataCardConst.JokerValues.Contains(x.Value)).ToList();
            // 判断是否都是王
            if (isAllJoker && bombCards.Count == 0)
            {
                cardStyleInfo = new CardStyleInfo(CardStyle, DataCardConst.JokerValues[0], group.Cards.Count);
                return true;
            }
            if (IsAllSame(bombCards) && bombCards.Count + group.LZCards.Count >= CardCnt)
            {
                var cardV = bombCards[0].Value;
                cardStyleInfo = new CardStyleInfo(CardStyle, cardV, group.Cards.Count);
                cardStyleInfo.CardLackValues = Enumerable.Repeat((int)cardV, group.LZCards.Count).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 jokerList = group.Cards.Where(x=>DataCardConst.JokerValues.Contains(x.Value)).ToList();
            if (eatStyleInfo == null)
                eatStyleInfo = new CardStyleInfo(CardStyle, 0, CardCnt);

            if (isAllJoker && jokerList.Count >= CardCnt)
            { // 先提示全王
                var tmpStyleInfo = new CardStyleInfo(CardStyle, DataCardConst.JokerValues[0], jokerList.Count);
                if (group.mStyleComparer.Greater(tmpStyleInfo, eatStyleInfo))
                {
                    groupList.Add(new CardGroupList(jokerList));
                }
            }

            var filterGroupList = group.CardGroupList.Where(x => x.Count >= CardCnt).ToList();
            for (int i = 0; i < filterGroupList.Count; i++)
            {
                var cardGroup = filterGroupList[i];
                if (IsJoker(cardGroup)) continue;
                var tmpStyleInfo = new CardStyleInfo(CardStyle, cardGroup.First().Value, cardGroup.Count);
                if (group.mStyleComparer.Greater(tmpStyleInfo, eatStyleInfo) && filterGroupList.Count > 1)
                {
                    groupList.Add(new CardGroupList(cardGroup));
                } else {
                    tmpStyleInfo = new CardStyleInfo(CardStyle, cardGroup.First().Value, cardGroup.Count + jokerList.Count);
                    if (group.mStyleComparer.Greater(tmpStyleInfo, eatStyleInfo))
                    {
                        var cardGroupList = new CardGroupList(cardGroup);
                        cardGroupList.AddRange(jokerList);
                        groupList.Add(cardGroupList);
                    }
                }
            }

            return groupList;
        }
        
        /// <summary>
        /// 获取所有得炸弹
        /// </summary>
        public List<CardGroupList> GetAllBombs(CardBaseGroup group)
        {
            List<CardGroupList> groupList = new List<CardGroupList>();
            var jokerList = group.Cards
                .Where(x => DataCardConst.JokerValues.Contains(x.Value) && x.CardType != DataCardConst.CardTypeLZ)
                .ToList();
            var descCardGroupList = group.CardGroupList.Select(x => x).OrderByDescending(x => x.Count).ToList();
            var lzCnt = group.LZCards.Count;
            for (int i = 0; i < descCardGroupList.Count; i++)
            {
                if (IsJoker(descCardGroupList[i]) ||descCardGroupList[i].Count + lzCnt < CardCnt) continue;
                CardGroupList cardGroupList = new CardGroupList();
                cardGroupList.AddRange(descCardGroupList[i]);
                if (lzCnt > 0)
                {
                    cardGroupList.AddRange(group.LZCards);
                    lzCnt = 0;
                }

                if (jokerList.Count > 0)
                {
                    cardGroupList.AddRange(jokerList);
                    jokerList.Clear();
                }

                CardStyleInfo styleInfo =
                    new CardStyleInfo(CardStyle, descCardGroupList[i].First().Value, cardGroupList.Count);
                cardGroupList.CardStyleInfo = styleInfo;
                groupList.Add(cardGroupList);
            }

            if (jokerList.Count > CardCnt && isAllJoker)
            {
                CardGroupList cardGroupList = new CardGroupList();
                cardGroupList.AddRange(jokerList);
                jokerList.Clear();
                CardStyleInfo styleInfo =
                    new CardStyleInfo(CardStyle, jokerList.First().Value, cardGroupList.Count);
                cardGroupList.CardStyleInfo = styleInfo;
                groupList.Add(cardGroupList);
            }

            return groupList;
        }
    }
}