using System;
using FairyGUI;
using Spine.Unity;
using UnityEngine;
using BingoBrain.Core;
using BingoBrain.Asset;
using UnityEngine.Events;
using System.Collections.Generic;
using Object = UnityEngine.Object;

namespace BingoBrain
{
    public class FX : BaseUnity<FX>
    {
        private string fxPath = "Effect/sys/";

        EffectPool<Fx_Type> _effectObjMonoObjPool;

        private Transform goWrapperPar;

        public override void Init()
        {
            base.Init();
            GameObject obj = new GameObject("FX_Pool");
            obj.transform.parent = transform;
            obj.transform.localPosition = Vector3.zero;
            obj.transform.localEulerAngles = Vector3.zero;
            _effectObjMonoObjPool = new EffectPool<Fx_Type>(obj.transform);
            _effectObjMonoObjPool.NewObjFunc = NewObjFunc;
            _effectObjMonoObjPool.GetObjFunc = GetObjFunc;
            _effectObjMonoObjPool.RecObjFunc = RecObjFunc;
        }

        private void RecObjFunc(Fx_Type arg1, Object arg2)
        {
            var component = arg2 as Component;
            if (component)
            {
                component.gameObject.SetActive(false);
            }
            else
            {
                (arg2 as GameObject)?.SetActive(false);
            }
        }

        private void GetObjFunc(Fx_Type arg1, Object arg2)
        {
            var component = arg2 as Component;
            if (component)
            {
                component.gameObject.SetActive(true);
            }
            else
            {
                (arg2 as GameObject)?.SetActive(true);
            }
        }


        private void NewObjFunc(Fx_Type arg, UnityAction<Object> action)
        {
            if ((int)arg < 100)
            {
                BetKit.Instance.LoadGameObjectAndClone($"Effect.spine.{arg}", arg.ToString(), (go) =>
                {
                    var sk = go.GetComponent<SkeletonAnimation>();
                    if (sk == null)
                    {
                        sk = go.GetComponentInChildren<SkeletonAnimation>();
                    }

                    action?.Invoke(sk);
                });
            }
            else
            {
                fxPath = $"Effect.sys.{arg}";
                BetKit.Instance.LoadGameObjectAndClone(fxPath, arg.ToString(), (go) =>
                {
                    ParticleSystem particleSystem = go.GetComponent<ParticleSystem>();
                    if (particleSystem == null)
                    {
                        particleSystem = go.GetComponentInChildren<ParticleSystem>();
                    }

                    if (particleSystem != null)
                    {
                        foreach (var item in particleSystem.GetComponentsInChildren<ParticleSystem>())
                        {
                            var main = item.main;
                            main.scalingMode = ParticleSystemScalingMode.Hierarchy;
                        }

                        particleSystem.transform.localScale = Vector3.one * 100;
                        action?.Invoke(particleSystem);
                    }
                    else
                    {
                        action?.Invoke(go);
                    }
                });
            }
        }

        public void GetFx<T>(Fx_Type fx_Type, UnityAction<T> action) where T : Object
        {
            _effectObjMonoObjPool.GetObject<T>(fx_Type, (obj) =>
            {
                var ani = obj as SkeletonAnimation;
                if (ani != null)
                {
                    ani.gameObject.layer = 0;
                    ani.ClearState();
                    ani.transform.localPosition = Vector3.zero;
                    ani.transform.localEulerAngles = Vector3.zero;
                }

                action?.Invoke(obj);
            });
        }

        public void RecFx<T>(Fx_Type fx_Type, T obj) where T : Object
        {
            _effectObjMonoObjPool.RecObject(fx_Type, obj);
        }

        public List<GameObject> gameObjects = new List<GameObject>();


        public override void Dispose()
        {
            base.Dispose();
            _effectObjMonoObjPool.Dispose();
        }

        public void SetFx<T>(GGraph gp, Fx_Type fx_Type, UnityAction<T> action, Action Rec = null) where T : Component
        {
            GetFx<T>(fx_Type, (fx) =>
            {
                if (fx != null)
                {
                    var goWrapper = new GoWrapper(fx.gameObject);
                    gp.SetNativeObject(goWrapper);
                    fx.transform.localPosition = Vector3.zero;
                    fx.transform.localScale = Vector3.one * 100;
                    fx.transform.localEulerAngles = Vector3.zero;
                    action?.Invoke(fx);
                    Rec += () =>
                    {
                        goWrapper.wrapTarget = null;
                        gp.SetNativeObject(null);
                        RecFx(fx_Type, fx);
                    };
                }
            });
        }

        internal T SetFx<T>(GGraph gp, Fx_Type fx_main_ad, Action closeCallback)
        {
            throw new NotImplementedException();
        }
    }

    public enum Fx_Type
    {
        None = -1,

        #region 骨骼动画

        /// <summary>
        /// 胜利结算飘带
        /// </summary>
        spine_reward = 0,

        /// <summary>
        /// 引导手
        /// </summary>
        fx_hand_pre,

        /// <summary>
        /// binggo
        /// </summary>
        spine_bingo,

        /// <summary>
        /// 主界面卡板
        /// </summary>
        spine_choice_card,
        spine_choice_card_b,
        spine_starreward,
        spine_starreward_bg,
        fx_first_reward,
        fx_main_ad,
        fx_broad,
        fx_tips,
                fx_savepot_icon,
        fx_savepot,
                fx_three_gift,
        fx_title_effect,
        fx_wheel,
        #endregion


        #region 粒子

        /// <summary>
        /// 货币资源入账
        /// </summary>
        fx_ui_jinbi_click = 107,

        /// <summary>
        /// 转盘进入特效
        /// </summary>
        fx_zhuangpan_enter,

        /// <summary>
        /// 签到头部背景
        /// </summary>
        fx_tanchuang_glow,

        /// <summary>
        /// 签到Icon
        /// </summary>
        fx_icon_glow,

        /// <summary>
        /// 叫号出现的特效
        /// </summary>
        fx_ball_enter,

        /// <summary>
        /// 选择转盘展示特效
        /// </summary>
        fx_zhuanpan_Select,

        #endregion
    }
}