using Cysharp.Threading.Tasks;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
using YooAsset;

public class UIManager : Singleton<UIManager>
{
    Dictionary<string, UIBase> openedUIs = new Dictionary<string, UIBase>();
    Dictionary<string, AssetHandle> assetHandles = new Dictionary<string, AssetHandle>();
    Stack<UIBase> uiStack = new Stack<UIBase>();

    public T ShowUI<T>(string uiName, RectTransform parent = null, bool isFull = false) where T : UIBase
    {
        T ui = null;
        string uiType = typeof(T).Name;
        if (!openedUIs.ContainsKey(uiName))
        {
            GameObject uiPrefab = LoadUI(uiType);
            ui = CreateUI<T>(uiPrefab, uiName, parent, isFull);
            openedUIs[uiName] = ui;
            uiStack.Push(ui);
        }
        else
        {
            ui = openedUIs[uiName] as T;
        }
        Debug.Log($"ShowUI====>name:{uiName} type:{typeof(T).Name}");
        ui.OnShow();
        return ui;
    }
    public async UniTask<T> ShowUIAsync<T>(string uiName, RectTransform parent = null, bool isFull = false) where T : UIBase
    {
        T ui = null;
        string uiType = typeof(T).Name;
        if (!openedUIs.ContainsKey(uiName))
        {
            GameObject uiPrefab = await LoadUIAsync(uiType);
            ui = CreateUI<T>(uiPrefab, uiName, parent, isFull);
            openedUIs[uiName] = ui;
            uiStack.Push(ui);
        }
        else
        {
            ui = openedUIs[uiName] as T;
        }
        Debug.Log($"ShowUIAsync====>name:{uiName} type:{typeof(T).Name}");
        ui.OnShow();
        return ui;
    }
    T CreateUI<T>(GameObject uiPrefab, string uiName, RectTransform parent = null, bool isFull = false) where T : UIBase
    {
        GameObject uiObj = GameObject.Instantiate(uiPrefab);
        uiObj.name = uiName;
        T ui = uiObj.GetComponent<T>();
        ui.OnCreate();
        if (parent) ui.SetParent(parent, isFull);
        Debug.Log($"CreateUI====>name:{uiName} type:{typeof(T).Name}");
        return ui;
    }
    GameObject LoadUI(string uiType)
    {
        if (!assetHandles.ContainsKey(uiType))
        {
            AssetHandle uiHandle = YooAssets.LoadAssetSync<GameObject>(uiType);
            assetHandles.Add(uiType, uiHandle);
            return (GameObject)uiHandle.AssetObject;
        }
        else
        {
            AssetHandle uiHandle = assetHandles[uiType];
            return (GameObject)uiHandle.AssetObject;
        }
    }
    async UniTask<GameObject> LoadUIAsync(string uiType)
    {
        if (!assetHandles.ContainsKey(uiType))
        {
            AssetHandle uiHandle = YooAssets.LoadAssetAsync<GameObject>(uiType);
            await uiHandle.ToUniTask();
            assetHandles.Add(uiType, uiHandle);
            return (GameObject)uiHandle.AssetObject;
        }
        else
        {
            AssetHandle uiHandle = assetHandles[uiType];
            return (GameObject)uiHandle.AssetObject;
        }
    }

    #region 用于测试没挂载UIBase的
    Dictionary<string, GameObject> testOpenedUIs = new Dictionary<string, GameObject>();
    Stack<GameObject> testUIStack = new Stack<GameObject>();
    public GameObject TestShowUI(string path, string uiName, RectTransform parent = null, bool isFull = false)
    {
        GameObject ui = null;
        if (!testOpenedUIs.ContainsKey(uiName))
        {
            GameObject uiPrefab = LoadUI(path);
            ui = TestCreateUI(uiPrefab, uiName, parent, isFull);
            testOpenedUIs[uiName] = ui;
            testUIStack.Push(ui);
        }
        else
        {
            ui = testOpenedUIs[uiName];
        }
        Debug.Log($"TestShowUI====>name:{uiName}");
        return ui;
    }
    public async UniTask< GameObject> TestShowUIAsync(string path, string uiName, RectTransform parent = null, bool isFull = false)
    {
        GameObject ui = null;
        if (!testOpenedUIs.ContainsKey(uiName))
        {
            GameObject uiPrefab = await LoadUIAsync(path);
            ui = TestCreateUI(uiPrefab, uiName, parent, isFull);
            testOpenedUIs[uiName] = ui;
            testUIStack.Push(ui);
        }
        else
        {
            ui = testOpenedUIs[uiName];
        }
        Debug.Log($"TestShowUI====>name:{uiName}");
        return ui;
    }
    GameObject TestCreateUI(GameObject uiPrefab, string uiName, RectTransform parent = null, bool isFull = false)
    {
        GameObject uiObj = GameObject.Instantiate(uiPrefab);
        uiObj.name = uiName;
        RectTransform ui = uiObj.GetComponent<RectTransform>();
        if (parent) TestSetParent(ui, parent, isFull);
        Debug.Log($"TestCreateUI====>name:{uiName}");
        return uiObj;
    }
    void TestSetFull(RectTransform rectTransform)
    {
        rectTransform.anchorMin = Vector2.zero;
        rectTransform.anchorMax = Vector2.one;
        rectTransform.offsetMin = Vector2.zero;
        rectTransform.offsetMax = Vector2.zero;
        rectTransform.sizeDelta = Vector2.zero;
    }

    void TestSetParent(RectTransform ui, RectTransform parent, bool isFull = false)
    {
        ui.SetParent(parent);
        ui.localScale = Vector3.one;
        ui.localPosition = Vector3.zero;
        ui.localRotation = Quaternion.identity;
        if (isFull)
            TestSetFull(ui);
    }
    #endregion 
}
