using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using TMPro;
using UnityEngine;

[assembly: InternalsVisibleTo("TFramework.Editor")]

namespace TFramework
{
    [DefaultExecutionOrder(-10000)]
    [AddComponentMenu("TFramework/全局管理(Main)")]
    [DisallowMultipleComponent]
    public class Main : SingletonBehaviourBase<Main>
    {
        [SerializeField]
        internal List<BaseManager> m_ManagerList = new List<BaseManager>();

        public bool IsEnableDebug;

        /// <summary>
        /// 供非Mono脚本使用Update事件
        /// </summary>
        public TAction onUpdate;

        protected override void Awake()
        {
            base.Awake();
        }

        // Start is called before the first frame update
        void Start()
        {
            if (IsEnableDebug)
                GetMagr<UIManager>().OpenUI<DebugPanel>();
        }

        // Update is called once per frame
        void Update()
        {
            onUpdate?.Invoke();
        }

        private void OnValidate()
        {
            if(IsEnableDebug)
            {
                if(m_ManagerList.Count <= 0||m_ManagerList.Find(m=>m is UIManager)==null)
                {
                    Log.Error("启用Debug工具失败，Debug工具依赖UIManager,请先注册UIManager");
                    IsEnableDebug = false;
                }
            }
        }

        protected override void OnDestroy()
        {
            if (IsEnableDebug)
                GetMagr<UIManager>().CloseUI<DebugPanel>(true);
            base.OnDestroy();
        }

        /// <summary>
        /// 获取指定类型管理器
        /// </summary>
        /// <typeparam name="T">管理器类型</typeparam>
        /// <returns>管理器</returns>
        public static T GetMagr<T>()where T:MonoBehaviour
        {
            T magr = Instance?.m_ManagerList.Find(p => p.GetType() == typeof(T)) as T;
            if (magr == null)
                Log.Error($"管理器{typeof(T).Name}未注册");
            return magr;
        }

        /// <summary>
        /// 延时执行
        /// </summary>
        /// <param name="time">延时时间</param>
        /// <param name="action">执行事件</param>
        public Coroutine Delay(float time, TAction action) => StartCoroutine(DelayAction(time, action));

        /// <summary>
        /// 延时执行
        /// </summary>
        /// <param name="time"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        private IEnumerator DelayAction(float time, TAction action)
        {
            yield return new WaitForSeconds(time);
            action?.Invoke();
        }
    }

    public delegate void TAction();
    public delegate void TAction<in T>(T arg0);
    public delegate void TAction<in T1, in T2>(T1 arg0, T2 arg1);
    public delegate void TAction<in T1, in T2, in T3>(T1 arg0, T2 arg1, T3 arg2);
    public delegate TRes TFunc<out TRes>();
    public delegate TRes TFunc<in T1, out TRes>(T1 arg0);
    public delegate TRes TFunc<in T1, in T2, out TRes>(T1 arg0, T2 arg1);

    public enum ResLoadMode
    {
        Resourece,
        AssetBundle
    }

    public enum UpdateMode
    {
        Editor,
        Loacl,
        Bulid
    }
}
