using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using Fort23.GameData;
using UnityEngine;
using Utility;

public class ConfigComponent : Singleton<ConfigComponent>
{
    private Dictionary<Type, ConfigHolder> _allConfigHolders = new Dictionary<Type, ConfigHolder>();

    private readonly Dictionary<string, Assembly> _assemblies = new Dictionary<string, Assembly>();

    public void Preload(bool isLogin = false)
    {
        string[] assemblyNames =
        {
            "GameData.dll"
        };
        foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
        {
            string assemblyName = $"{assembly.GetName().Name}.dll";
            if (!((IList)assemblyNames).Contains(assemblyName))
            {
                continue;
            }

            _assemblies[assemblyName] = assembly;
        }

        _allConfigHolders.Clear();
        ConfigHolder configHolder = null;

        Assembly gameDataAssembly = _assemblies["GameData.dll"];


        foreach (Type type in gameDataAssembly.GetTypes())
        {
            object[] attrs = type.GetCustomAttributes(typeof(ConfigAttribute), false);
            if (attrs.Length == 0)
            {
                continue;
            }


            try
            {
                ConfigAttribute configAttribute =
                    type.GetCustomAttribute(typeof(ConfigAttribute)) as ConfigAttribute;
                if (configAttribute != null)
                {
                    TextAsset ta = Resources.Load<TextAsset>("Config/" + configAttribute.prefab);


                    configHolder = JsonHelper.FromJson(ta.text, type) as ConfigHolder;


                    if (configHolder != null)
                    {
                        configHolder.Init();

                        _allConfigHolders[configHolder.ConfigType] = configHolder;
                    }
                    else
                    {
                        Debug.LogError($"JSON转{type.Name}失败!");
                    }
                }
                else
                {
                    Debug.LogError($"配置文件类{type.Name}没有添加ConfigAttribute!");
                }
            }
            catch (Exception e)
            {
                Debug.LogError("导表错误" + type);
            }
        }
    }


    public T Get<T>(int ID) where T : struct, IConfig
    {
        ConfigHolder configHolder;
        if (!_allConfigHolders.TryGetValue(typeof(T), out configHolder))
        {
            Debug.LogException(new Exception($"ConfigComponent not found key: {typeof(T).FullName}"));
            return default;
        }

        IConfig iconfig = configHolder.TryGet(ID);
        return iconfig is T ? (T)iconfig : default;
    }


    public T[] GetAll<T>() where T : struct, IConfig
    {
        ConfigHolder configHolder;
        if (!_allConfigHolders.TryGetValue(typeof(T), out configHolder))
        {
            throw new Exception($"ConfigComponent not found key: {typeof(T).FullName}");
        }

        List<IConfig> lists = configHolder.GetAll();
        T[] configs = new T[configHolder.GetAll().Count];
        for (int i = 0; i < configs.Length; i++)
        {
            IConfig iconfig = lists[i];
            configs[i] = iconfig is T ? (T)iconfig : default;
        }

        return configs;
    }
}