using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;

/// <summary>
/// 可以根据需求继续增加层级
/// </summary>
public enum E_UI_Layer
{
    /// <summary>
    /// 最下层
    /// </summary>
    Bot,
    /// <summary>
    /// 中间层 
    /// </summary>
    Mid,
    /// <summary>
    /// 上层 加载页面 
    /// </summary>
    Top,
    /// <summary>
    /// 最上层 系统层 警告、错误 
    /// </summary>
    System,
}

/// <summary>
/// UI管理器
/// 
/// </summary>
public class UIManager : BaseManager<UIManager>
{ 
    /// <summary>
    /// 底层、中层、上层、系统层
    /// </summary>
    private readonly Transform bot,mid,top,system;

    /// <summary>
    /// canvas
    /// </summary>
    public RectTransform canvas;

    /// <summary>
    /// 存储显示的panel
    /// </summary>
    private readonly Dictionary<string ,BasePanel> panelDic = new Dictionary<string, BasePanel> ();

    /// <summary>
    /// 构造函数
    /// </summary>
    private UIManager()
    {
        canvas = ResourcesManager.Instance.Load<GameObject>("UI/Base/Canvas").GetComponent<RectTransform>();
        GameObject.DontDestroyOnLoad(canvas.gameObject);
        bot = canvas.transform.Find("Bot");
        mid = canvas.transform.Find("Mid");
        top = canvas.transform.Find("Top");
        system = canvas.transform.Find("System");
    }

    /// <summary>
    /// 显示面板   要求：面板类型和面板名称相同 
    /// </summary>
    /// <typeparam name="T">面板类型 面板名称</typeparam>
    /// <param name="layer">显示在哪一层</param>
    /// <param name="action">加载完成后 要做的</param>
    public void ShowPanel<T>(E_UI_Layer layer = E_UI_Layer.Mid, UnityAction<T> action = null) where T : BasePanel
    {
        string panelName = typeof(T).Name;
        //重复调用问题 1 已经存在的panel
        if (panelDic.ContainsKey(panelName))
        {
            panelDic[panelName].ShowMe();
            action?.Invoke(panelDic[panelName] as T);
            return;
        }
        //重复调用 同一帧调用多次问题
        ResourcesManager.Instance.LoadAsync<GameObject>("UI/UI_Panel/" + panelName, (panelObj) =>
        {
            Transform uilayer = bot;
            switch (layer)
            {
                case E_UI_Layer.Mid:
                    uilayer = mid;
                    break;
                case E_UI_Layer.Top:
                    uilayer = top;
                    break;
                case E_UI_Layer.System:
                    uilayer = system;
                    break;
            }
            panelObj.transform.SetParent(uilayer);
            panelObj.transform.localPosition = Vector3.zero;
            panelObj.transform.localRotation = Quaternion.identity;
            panelObj.transform.localScale = Vector3.one;
            (panelObj.transform as RectTransform).offsetMax = Vector3.zero;
            (panelObj.transform as RectTransform).offsetMin = Vector3.zero;
            T panel = panelObj.GetComponent<T>();
            panel.ShowMe();
            action?.Invoke(panel);
            panelDic.Add(panelName, panel);
        });
    }

    /// <summary>
    /// 隐藏面板
    /// </summary>
    /// <param name="panelName"></param>
    public void HidePanel<T>() where T : BasePanel
    {
        string panelName = typeof(T).Name;
        if (panelDic.ContainsKey(panelName))
        {
            panelDic[panelName].HideMe();
            GameObject.Destroy(panelDic[panelName].gameObject);
            panelDic.Remove(panelName);
        }
        else
        {
            Debug.Log("显示的面板中不存在要隐藏的面板！！！！");
        }
    }

    /// <summary>
    /// 获取一个已显示的面板
    /// </summary>
    /// <typeparam name="T">想要获取的面板脚本</typeparam>
    /// <returns></returns>
    public T GetPanel<T>() where T :BasePanel
    {
        string panelName = typeof(T).Name;
        if(panelDic.ContainsKey(panelName))
        {
            return panelDic[panelName] as T;
        }
        return null;
    }

    /// <summary>
    /// 获取UI面板层
    /// </summary>
    /// <param name="layer"></param>
    /// <returns></returns>
    public Transform GetLayer(E_UI_Layer layer)
    {
        switch (layer)
        {
            case E_UI_Layer.Bot:
                return bot;
            case E_UI_Layer.Mid:
                return mid;
            case E_UI_Layer.Top:
                return top;
            case E_UI_Layer.System:
                return system;
            default:
                return null;
        }
    }

    /// <summary>
    /// 给控件添加自定义事件
    /// </summary>
    /// <param name="control">控件对象</param>
    /// <param name="type">事件类型</param>
    /// <param name="action">委托</param>
    public static void AddEventTriggerListener(UIBehaviour control, EventTriggerType type,UnityAction<BaseEventData> action)
    {
        EventTrigger eventTrigger = control.GetComponent<EventTrigger>();
        if (eventTrigger == null)
            eventTrigger = control.GetComponent<EventTrigger>();
        EventTrigger.Entry entry = new EventTrigger.Entry();
        entry.eventID = type;
        entry.callback.AddListener(action);
        eventTrigger.triggers.Add(entry);
    }
}
