using System.Reflection;

namespace AyCode.Core.Helpers;

public sealed class ConstHelper
{
    private static readonly Dictionary<string, Dictionary<int, string>?> ObjectsByNamesByValue = new();

    public static string NameByValue<T>(int value) where T : class
        => GetNameByValue(GetNamesByType(typeof(T).Name) ?? FillNames<T>(), value);

    public static string NameByValue(string typeName, int value)
        => GetNameByValue(GetNamesByType(typeName), value);


    private static string GetNameByValue(IReadOnlyDictionary<int, string>? namesByValue, int value)
        => namesByValue != null && namesByValue.TryGetValue(value, out var fieldName) ? $"tag: {fieldName}_{value}" : $"..._{value}";

    private static Dictionary<int, string>? GetNamesByType(string typeName)
    {
        lock (ObjectsByNamesByValue)
        {
            if (ObjectsByNamesByValue.TryGetValue(typeName, out var namesByValue) && namesByValue!.Count > 0)
                return namesByValue;
        }

        return null;
    }

    private static Dictionary<int, string> FillNames<T>() where T : class
    {
        var objectType = typeof(T);
        var namesByValue = new Dictionary<int, string>();

        lock (ObjectsByNamesByValue)
        {
            foreach (var fieldInfo in objectType.GetFields().Where(x => (x.Attributes & FieldAttributes.Literal) != 0 && x.FieldType == typeof(int)))
            {
                namesByValue[(int)fieldInfo.GetValue(null)!] = fieldInfo.Name;
            }

            ObjectsByNamesByValue[objectType.Name] = namesByValue;
        }

        return namesByValue;
    }
}