using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ResourcePool : MonoBehaviour
{
    private class EmojiPool : ListItemBase<string>
    {
        public CommonPool<RectTransform> emojiPool { get; private set; }

        public void Init(RectTransform prefab, Transform root)
        {
            emojiPool = new CommonPool<RectTransform>(root, prefab);
        }
    }

    #region static

    private static ResourcePool _instance;

    public static ResourcePool Instance
    {
        get
        {
            if (_instance == null)
            {
                var gameobj = new GameObject("ResourcePool");
                _instance = gameobj.AddComponent<ResourcePool>();
            }

            return _instance;
        }
    }

    // Use this for initialization
    private void Start()
    {
        DontDestroyOnLoad(gameObject);
    }

    #endregion


    #region Emoji System

    private List<EmojiPool> _emojiPool;

    public RectTransform PullEmoji(string emojiName, Transform parent)
    {
        var pool = _emojiPool.GetItem(emojiName, ListGetMode.get);
        return pool == null ? null : pool.emojiPool.PullItem(parent);
    }

    public void PushEmoji(RectTransform emojiItem)
    {
        var pool = _emojiPool.GetItem(emojiItem.gameObject.name, ListGetMode.get);
        if (pool != null)
            pool.emojiPool.PushItem(emojiItem);
    }

    public void InitEmoji(int emojiCnt)
    {
        if (_emojiPool == null)
        {
            _emojiPool = new List<EmojiPool>();
            for (var i = 0; i < emojiCnt; i++)
            {
                var id = i + 1;
                LoadAssetBundle.Instance.LoadGameObject(LoadAssetBundle.BUNDLE_PATH_UI + "emoji/", "Emoji" + id,
                    LoadEmojiFinish, null);
            }
        }
    }

    private void LoadEmojiFinish(string emojiName, GameObject resObj, Hashtable hashParam)
    {
        var prefab = resObj.transform as RectTransform;
        if (prefab)
        {
            var pool = _emojiPool.GetItem(emojiName, ListGetMode.create);
            pool.Init(prefab, transform);
        }
    }

    #endregion

    #region UIItemPool

    private readonly Dictionary<string, Stack<GameObject>> _IdleUIItems = new Dictionary<string, Stack<GameObject>>();

    public T GetIdleUIItem<T>(GameObject itemPrefab, Transform parentTrans = null)
    {
        GameObject idleItem = null;
        if (_IdleUIItems.ContainsKey(itemPrefab.name))
            if (_IdleUIItems[itemPrefab.name].Count > 0)
                idleItem = _IdleUIItems[itemPrefab.name].Pop();

        if (idleItem == null) idleItem = Instantiate(itemPrefab);
        idleItem.gameObject.SetActive(true);
        if (parentTrans != null)
        {
            idleItem.transform.SetParent(parentTrans);
            idleItem.transform.localPosition = Vector3.zero;
            idleItem.transform.localRotation = Quaternion.Euler(Vector3.zero);
            idleItem.transform.localScale = Vector3.one;
        }

        return idleItem.GetComponent<T>();
    }

    public T GetIdleUIItem<T>(string itemPrefabName, Transform parentTrans = null)
    {
        GameObject idleItem = null;
        if (_IdleUIItems.ContainsKey(itemPrefabName))
        {
            if (_IdleUIItems[itemPrefabName].Count > 1)
            {
                idleItem = _IdleUIItems[itemPrefabName].Pop();
            }
            else if (_IdleUIItems[itemPrefabName].Count == 1)
            {
                var go = _IdleUIItems[itemPrefabName].Peek();
                idleItem = Instantiate(go);
            }
        }

        if (idleItem == null)
            return default(T);

        return idleItem.GetComponent<T>();
    }

    public void RecvIldeUIItem(GameObject itemBase)
    {
        StartCoroutine(RecvIdleUIItemDelay(itemBase));
    }

    public void RecvIldeUIItemImmediately(GameObject itemBase)
    {
        RecvIdleUIItem(itemBase);
    }


    private IEnumerator RecvIdleUIItemDelay(GameObject itemBase)
    {
        yield return new WaitForFixedUpdate();
        RecvIdleUIItem(itemBase);
    }

    private void RecvIdleUIItem(GameObject itemBase)
    {
        if (itemBase == null)
            return;
        var itemName = itemBase.name.Replace("(Clone)", "");
        if (!_IdleUIItems.ContainsKey(itemName)) _IdleUIItems.Add(itemName, new Stack<GameObject>());
        itemBase.gameObject.SetActive(false);
        itemBase.transform.SetParent(transform);
        if (!_IdleUIItems[itemName].Contains(itemBase)) _IdleUIItems[itemName].Push(itemBase);
    }

    public void ClearUIItems()
    {
        foreach (var uiItem in _IdleUIItems)
            while (uiItem.Value.Count > 0)
            {
                var uiItemGO = uiItem.Value.Pop();
                Destroy(uiItemGO);
            }

        _IdleUIItems.Clear();
    }

    #endregion
}