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

namespace XGame.Framework.ObjectCollection
{
    [Serializable]
    public class ObjectCollector : IObjectCollector
    {
#if UNITY_EDITOR
        public Type collectorType = typeof(GameObject);
        public Type objectType = typeof(UnityEngine.Object);
        public Type[] blackTypes = null;
        public bool isGenerate = false;
#endif

        [SerializeField]
        public List<string> keys = new List<string>();

        [SerializeField]
        public List<UnityEngine.Object> values = new List<UnityEngine.Object>();

        private Dictionary<string, UnityEngine.Object> componentsDict;
        private bool dictCached = false;

        public UnityEngine.Object this[string key]
        {
            get
            {
                if (!dictCached) CacheDict();
                if (componentsDict.TryGetValue(key, out UnityEngine.Object value))
                    return value;
                Log.Error($"Can't find the key: {key}, Please Check it");
                return null;
            }
        }

        public List<string> Keys => keys;

        public List<UnityEngine.Object> Objects => values;

        public T GetComponent<T>(string key) where T : Component
        {
            var obj = this[key];
            if (obj is GameObject go)
            {
                return go.GetComponent<T>();
            }
            if (obj is Component component)
            {
                return component.gameObject.GetComponent<T>();
            }
            Log.Error($"Can't find Component. key: {key} Type:{typeof(T)}");
            return null;
        }

        public GameObject GetGameObject(string key)
        {
            var obj = this[key];
            if (obj is GameObject go)
            {
                return go;
            }
            Log.Error($"Can't find GameObject. key: {key}");
            return null;
        }

        private void CacheDict()
        {
            dictCached = true;

            componentsDict = new Dictionary<string, UnityEngine.Object>(keys.Count);
            for (int i = 0, length = keys.Count; i < length; i++)
            {
                componentsDict[keys[i]] = values[i];
            }
        }
    }
}
