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

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

        public override void Init()
        {
            base.Init();
            GameDispatcher.Instance.AddPriorityListener(BingoInfo.SelectOneNum, OnSelectOneCard);
            GameDispatcher.Instance.AddListener(BingoInfo.EndBingoGame, OnEndBingoGame);
            GameDispatcher.Instance.AddListener(BingoInfo.AddMoneyCell, OnAddMoneyCell);
        }

        private void OnAddMoneyCell(object obj)
        {
            var count = (int)obj;

            var finalList = new List<CardEntity>();
            foreach (var list in from cardBoard in BingoCell.cardBoardList
                     where !cardBoard.isFinish
                     select GlobalHarmony.GetRandomList(cardBoard.cardList.FindAll(GameHelper.IsCommonCard),
                         count))
            {
                if (list.Count != 0)
                {
                    foreach (var card in list)
                    {
                        card.data.type = CardPropType.cash;
                    }
                }

                finalList.AddRange(list);
            }

            var path = "Prefab.Game.PropItem";
            var time = 0.5f;

            if (finalList.Count != 0)
            {
                foreach (var card in finalList)
                {
                    var reward = Battle.Instance.ShungTik.Get(path, "reward3");
                    var finalPos = card.Game.transform.position;
                    reward.transform.SetParent(BingoCell.root, false);

                    var originPos =
                        CameraBoardk.Instance.FGUIPosToWorldPos(new Vector3(GRoot.inst.width / 2,
                            GRoot.inst.height / 2));

                    reward.transform.position = originPos;
                    reward.transform.localScale = Vector3.one * 0.5f;

                    reward.transform.DOScale(1, time);
                    reward.transform.DOMove(finalPos, time).OnComplete(delegate
                    {
                        var rainbow = Battle.Instance.ShungTik.Get("Effect.spark", "fx_skill_enter");
                        rainbow.transform.SetParent(card.Game.transform, false);
                        DOVirtual.DelayedCall(1, () => { Battle.Instance.ShungTik.Release(rainbow); });
                        card.SetReward();

                        Battle.Instance.ShungTik.Release(reward);
                    });
                }
            }
        }

        private void OnEndBingoGame(object obj)
        {
            BingoCell.curEnergy = 0;
        }

        private void OnSelectOneCard(object obj)
        {
            if (BingoCell.isFirstGame)
            {
                return;
            }

            if (BingoCell.isPropRewarding)
            {
                return;
            }

            BingoCell.curEnergy++;
            if (BingoCell.IsFullEnergy)
            {
                DOVirtual.DelayedCall(Time.deltaTime, delegate
                {
                    BingoCell.isPropRewarding = true;

                    RandomReward();
                });
            }
        }

        private int rewardType;
        int coinType = 1;
        int x3Type = 2;
        int daubType = 0;


        List<int> typeIdList = new List<int>
        {
            108, 107, 109
        };

        private void RandomReward()
        {
            rewardType = Random.Range(0, 3);

            GameDispatcher.Instance.Dispatch(BingoInfo.StartFullEnergy, rewardType);

            if (PreferencesMgr.Instance.IsFirstPropFull)
            {
                PreferencesMgr.Instance.IsFirstPropFull = false;
                UICtrlDispatcher.Instance.Dispatch(SkinInfo.PropInfoUI_Open);
                UICtrlDispatcher.Instance.AddOnceListener(SkinInfo.PropInfoUI_Close, a => { DoProp(); });
            }
            else
            {
                DoProp();
            }
        }

        int GetCountByType()
        {
            var id = typeIdList[rewardType];
            var vo = ConfigSystem.GetConfig<PropModel>().dataList.FirstOrDefault(prop => prop.id == id);
            return vo.quantity[PreferencesMgr.Instance.CardBoardIndex];
        }

        void DoProp()
        {
            var count = GetCountByType();
            var finalList = new List<CardEntity>();


            if (rewardType == coinType)
            {
                foreach (var list in from cardBoard in BingoCell.cardBoardList
                         where !cardBoard.isFinish
                         select GlobalHarmony.GetRandomList(cardBoard.cardList.FindAll(GameHelper.IsCommonCard),
                             count))
                {
                    if (list.Count != 0)
                    {
                        foreach (var card in list)
                        {
                            card.data.type = CardPropType.coin;
                        }
                    }

                    finalList.AddRange(list);
                }
            }

            else if (rewardType == x3Type)
            {
                foreach (var list in from cardBoard in BingoCell.cardBoardList
                         where !cardBoard.isFinish
                         select GlobalHarmony.GetRandomList(cardBoard.cardList.FindAll(tmp =>
                             tmp.data.type is CardPropType.cash or CardPropType.coin && !tmp.data.isSelect &&
                             !tmp.data.isDelaySelect), count))
                {
                    if (list.Count != 0)
                    {
                        foreach (var card in list)
                        {
                            card.data.type = card.data.type == CardPropType.cash
                                ? CardPropType.cashx3
                                : CardPropType.coinx3;
                        }
                    }

                    finalList.AddRange(list);
                }
            }

            else if (rewardType == daubType)
            {
                foreach (var card in BingoCell.cardBoardList.Where(cardBoard => !cardBoard.isFinish).SelectMany(
                             cardBoard => cardBoard.cardList.Where(GameHelper.IsCommonCard)
                                 .Where(card => !BingoCell.calledList.Contains(card.data.num))))
                {
                    if (card.data.isSelect)
                    {
                        Debug.Log(card.data.index);
                    }

                    finalList.Add(card);
                }

                finalList = GlobalHarmony.GetRandomList(finalList, count);

                foreach (var card in finalList)
                {
                    card.AddToSelectedList();
                }
            }

            var path = "Prefab.Game.PropItem";
            var time = 0.5f;
            Audio.Instance.PlayDynamicEffect("prop_ready");
            if (finalList.Count != 0)
            {
                DOVirtual.DelayedCall(1.5f, () =>
                {
                    var cardBoardList = new List<CardBoardEntity>();
                    Audio.Instance.PlayDynamicEffect("prop_fly");

                    foreach (var card in finalList)
                    {
                        var reward = Battle.Instance.ShungTik.Get(path, $"reward{rewardType}");
                        var finalPos = card.Game.transform.position;
                        reward.transform.SetParent(BingoCell.root.transform, false);
                        var originPos = BingoCell.propOriginPos;
                        reward.transform.position = originPos;
                        reward.transform.localScale = Vector3.one * 0.5f;
                        if (rewardType == daubType)
                        {
                            if (!cardBoardList.Contains(card.data.cardBoard))
                            {
                                cardBoardList.Add(card.data.cardBoard);
                            }
                        }

                        reward.transform.DOScale(1, time);
                        reward.transform.DOMove(finalPos, time).OnComplete(delegate
                        {
                            if (rewardType == daubType)
                            {
                                card.SetByData();
                                var boom = Battle.Instance.ShungTik.Get("Effect.spark.fx_skill_boom",
                                    "fx_skill_boom");
                                boom.transform.SetParent(card.Game.transform, false);
                                DOVirtual.DelayedCall(1, () => { Battle.Instance.ShungTik.Release(boom); });
                            }
                            else
                            {
                                var rainbow = Battle.Instance.ShungTik.Get("Effect.spark.fx_skill_enter",
                                    "fx_skill_enter");
                                rainbow.transform.SetParent(card.Game.transform, false);
                                DOVirtual.DelayedCall(1,
                                    () => { Battle.Instance.ShungTik.Release(rainbow); });
                                card.SetReward();
                            }

                            Battle.Instance.ShungTik.Release(reward);
                        });
                    }

                    if (cardBoardList.Count != 0)
                        DOVirtual.DelayedCall(time, delegate
                        {
                            var effectName = "";
                            if (rewardType == coinType)
                            {
                                effectName = "prop_coin";
                            }
                            else if (rewardType == x3Type)
                            {
                                effectName = "propx3";
                            }
                            else
                            {
                                effectName = "prop_daub";
                            }

                            Audio.Instance.PlayDynamicEffect(effectName);


                            foreach (var cardBoard in cardBoardList)
                            {
                                cardBoard.DelayCheckBingo();
                            }
                        });
                });
                DOVirtual.DelayedCall(3.5f, () =>
                {
                    BingoCell.curEnergy = 0;
                    BingoCell.isPropRewarding = false;
                    GameDispatcher.Instance.Dispatch(BingoInfo.AddPropRewardFinish);
                });
            }
            else
            {
                DOVirtual.DelayedCall(1.5f, () =>
                {
                    BingoCell.curEnergy = 0;
                    BingoCell.isPropRewarding = false;
                    GameDispatcher.Instance.Dispatch(BingoInfo.AddPropRewardFinish);
                });
            }
        }
    }
}