using System.Linq;
using DG.Tweening;
using BingoBrain.Core;
using UnityEngine;
using BingoBrain.HotFix;
using System.Collections.Generic;

namespace BingoBrain
{
    public class CardBoardSystem : BaseSystem
    {
        public CardBoardSystem(bool isAutoInit = true)
        {
            if (isAutoInit)
            {
                Init();
            }
        }

        public override void Init()
        {
            base.Init();

            GameDispatcher.Instance.AddListener(BingoInfo.FinishOneCardBoard, OnFinishOneCardBoard);
            GameDispatcher.Instance.AddListener(BingoInfo.StartBingoGame, OnStartBingoGame);
            GameDispatcher.Instance.AddListener(BingoInfo.EndBingoGame, OnEndBingoGame);
            GameDispatcher.Instance.AddListener(BingoInfo.AddPropRewardFinish, OnAddPropRewardFinish);
            GameDispatcher.Instance.AddListener(BingoInfo.CallNum, OnCallNum);
            GameDispatcher.Instance.AddListener(BingoInfo.CheckBingo, OnCheckBingo);

            cardBoardPool = new Jcna<CardBoardEntity>(OnGet, OnRelease);
        }

        private void OnCheckBingo(object obj)
        {
            var index = (int)obj;
            for (var i = 0; i < BingoCell.cardBoardList.Count; i++)
            {
                var cardBoard = BingoCell.cardBoardList[i];
                if (cardBoard.data.index == index || cardBoard.isFinish)
                {
                    continue;
                }


                cardBoard.CheckBingo();
            }
        }

        private void OnAddPropRewardFinish(object obj)
        {
        }

        private void OnCallNum(object obj)
        {
            var num = (int)obj;
            foreach (var card in BingoCell.cardBoardList.SelectMany(cardBoard =>
                         cardBoard.cardList.Where(card => !card.data.isSelect && !card.data.isCoin)
                             .Where(card => card.data.num == num)))
            {
                card.TweenAlphaNum();
            }
        }

        private void OnEndBingoGame(object obj)
        {
            ResetCardBoard();
        }

        private void OnStartBingoGame(object obj)
        {
            PreferencesMgr.Instance.GameSum++;
            InitCardBoardData();
        }

        private void OnRelease(CardBoardEntity obj)
        {
            if (obj.GoCell.gameObject != null)
            {
                obj.GoCell.gameObject.SetActive(false);
            }
        }

        private void OnGet(CardBoardEntity obj)
        {
            if (obj.GoCell.gameObject != null)
            {
                obj.GoCell.gameObject.SetActive(true);
            }
        }

        #region 变量

        Jcna<CardBoardEntity> cardBoardPool;

        #endregion

        #region 流程

        void InitCardBoardData()
        {
            for (var i = 0; i < BingoCell.CardBoardCount; i++)
            {
                var entity = cardBoardPool.Get();
                var cardBoardData = entity.data;
                cardBoardData.index = i;
                for (var j = 0; j < BingoCell.bingoCount; j++)
                {
                    var startNum = 1 + 15 * j;
                    var endNum = 15 + 15 * j;
                    for (var k = 0; k < BingoCell.bingoCount; k++)
                    {
                        var num = Random.Range(startNum, endNum + 1);
                        while (cardBoardData.cardNumList.Contains(num))
                        {
                            if (BingoCell.bingoCount >= 15)
                            {
                                return;
                            }

                            num = Random.Range(startNum, endNum + 1);
                        }

                        cardBoardData.cardNumList.Add(num);
                    }
                }

                entity.data.selectList.Add(BingoCell.FixedNum);
                entity.SetData();
                BingoCell.cardBoardList.Add(entity);
            }


            var finalList = new List<CardEntity>();
            foreach (var card in BingoCell.cardBoardList.Where(cardBoard => !cardBoard.isFinish)
                         .SelectMany(cardBoard => cardBoard.cardList.Where(GameHelper.IsCommonCard)))
            {
                if (card.data.isSelect)
                {
                    Debug.Log(card.data.index);
                }

                finalList.Add(card);
            }

            finalList = GlobalHarmony.GetRandomList(finalList,
                ConfigSystem.GetConfig<CommonModel>().Initialcardprop);
            if (finalList.Count != 0)
            {
                foreach (var card in finalList)
                {
                    card.data.type = CardPropType.fanpai;
                    card.SetReward();
                }
            }

            switch (BingoCell.CardBoardCount)
            {
                case 1:
                    BingoCell.cardBoardList[0].GoCell.gameObject.SetActive(true);
                    BingoCell.cardBoardList[0].GoCell.transform.localScale = Vector3.one;
                    BingoCell.cardBoardList[0].GoCell.transform.localPosition = new Vector3(0, -1);
                    break;
                case 2:
                {
                    IsfvKit.DelayedAction(0.1f, () =>
                    {
                        for (var i = 0; i < 2; i++)
                        {
                            BingoCell.cardBoardList[i].GoCell.gameObject.SetActive(true);
                            BingoCell.cardBoardList[i].GoCell.transform.localScale = Vector3.one * 0.63f;
                            var symbol = i == 0 ? -1 : 1;
                            BingoCell.cardBoardList[i].GoCell.transform.localPosition = Vector3.zero;
                            BingoCell.cardBoardList[i].GoCell.transform
                                .DOLocalMove(new Vector3(0, symbol * 3.3f - 2f), 0.2f).SetEase(Ease.Linear);
                            BingoCell.cardBoardList[i].bingGoSke.transform.localScale = Vector3.one;
                        }
                    });

                    break;
                }
                case 4:
                {
                    IsfvKit.DelayedAction(0.1f, () =>
                    {
                        for (var i = 0; i < 4; i++)
                        {
                            BingoCell.cardBoardList[i].GoCell.transform.localScale = Vector3.one * 0.58f;
                            var symbolX = i % 2 == 0 ? -1 : 1;
                            var symbolY = i / 2 == 0 ? -1 : 1;
                            BingoCell.cardBoardList[i].GoCell.transform.localPosition = Vector3.zero;
                            BingoCell.cardBoardList[i].GoCell.transform
                                .DOLocalMove(new Vector3(symbolX * 2.57f, symbolY * 3 - 1.5f), 0.2f)
                                .SetEase(Ease.Linear);
                            BingoCell.cardBoardList[i].bingGoSke.transform.localScale = Vector3.one;
                        }
                    });

                    break;
                }
            }
        }

        private void OnFinishOneCardBoard(object obj)
        {
            if (BingoCell.IsPauseGame)
            {
                return;
            }


            if (BingoCell.isVictory)
            {
                return;
            }

            var isFinish = BingoCell.cardBoardList.All(cardBoard => cardBoard.isFinish);

            if (isFinish)
            {
                if (!BingoCell.IsInGame)
                {
                    return;
                }

                BingoCell.isVictory = true;
                DOVirtual.DelayedCall(1, delegate { GameDispatcher.Instance.Dispatch(BingoInfo.ShowGameOver); });
            }
        }

        void ResetCardBoard()
        {
            foreach (var cardBoard in BingoCell.cardBoardList)
            {
                cardBoard.OnReset();
                cardBoardPool.Release(cardBoard);
            }

            BingoCell.cardBoardList.Clear();
            BingoCell.bingoCardboardIndex = -1;
            BingoCell.isVictory = false;
            BingoCell.PauseSum = 0;
        }

        #endregion
    }
}