using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace OASystem.Domain.Enums
{
    public static class EnumHelper
    {
        //--extension
        /// <summary>
        /// 获取当前枚举描述
        /// </summary>
        /// <param name="enumValue"></param>
        /// <returns></returns>
        public static string GetEnumDescription(this Enum enumValue)
        {
            try
            {
                Type type = enumValue.GetType();
                MemberInfo[] memInfo = type.GetMember(enumValue.ToString());
                if (null != memInfo && memInfo.Length > 0)
                {
                    object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
                    if (null != attrs && attrs.Length > 0)
                        return ((DescriptionAttribute)attrs[0]).Description;
                }
                return enumValue.ToString();
            }
            catch (Exception)
            {
                return "";
            }
        }

        //根据值获取枚举方法
        public static Enum GetEnumByValue(Type enumType, string value)
        {
            return Enum.Parse(enumType, value) as Enum;
        }

        /// <summary>
        /// 根据Key获取枚举描述
        /// </summary>
        /// <param name="en"></param>
        /// <returns></returns>
        public static string GetDescription(this System.Enum en)
        {
            Type type = en.GetType();
            MemberInfo[] memInfo = type.GetMember(en.ToString());
            if (memInfo != null && memInfo.Length > 0)
            {
                object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
                if (attrs != null && attrs.Length > 0)
                    return ((DescriptionAttribute)attrs[0]).Description;
            }
            return en.ToString();
        }
        /// <summary>
        /// 根据枚举类型得到其所有的 值 与 枚举定义Description属性 的集合
        /// </summary>
        /// <param name="enumType"></param>
        /// <returns></returns>
        public static NameValueCollection GetNVCFromEnumValue(Type enumType)
        {
            NameValueCollection nvc = new NameValueCollection();
            Type typeDescription = typeof(DescriptionAttribute);
            System.Reflection.FieldInfo[] fields = enumType.GetFields();
            string strText = string.Empty;
            string strValue = string.Empty;
            foreach (FieldInfo field in fields)
            {
                if (field.FieldType.IsEnum)
                {
                    //strValue = ((int)enumType.InvokeMember(field.Name, BindingFlags.GetField, null, null, null)).ToString();
                    strValue = (enumType.InvokeMember(field.Name, BindingFlags.GetField, null, null, null) as int?)?.ToString() ?? string.Empty;
                    object[] arr = field.GetCustomAttributes(typeDescription, true);
                    if (arr.Length > 0)
                    {
                        DescriptionAttribute aa = (DescriptionAttribute)arr[0];
                        strText = aa.Description;
                    }
                    else
                    {
                        strText = "";
                    }
                    nvc.Add(strValue, strText);
                }
            }
            return nvc;
        }

        /// <summary>
        /// 获取枚举的所有值及其对应的描述
        /// </summary>
        /// <param name="enumType"></param>
        /// <param name="enumKeys"></param>
        /// <returns></returns>
        public static Dictionary<string, string> GetEnumDescriptions(Type enumType, string[]? enumKeys = null)
        {
            var descriptions = new Dictionary<string, string>();
            if (!enumType.IsEnum)
            {
                return descriptions;
                //throw new ArgumentException("Type must be an enum", nameof(enumType));
            }


            foreach (var field in enumType.GetFields(BindingFlags.Static | BindingFlags.GetField | BindingFlags.Public))
            {
                var descriptionAttribute = field.GetCustomAttribute<DescriptionAttribute>();
                var description = descriptionAttribute?.Description ?? field.Name;
                var name = field.Name;
                if (enumKeys != null && enumKeys.Any())
                {
                    if (!enumKeys.Contains(name))
                    {
                        descriptions[name] = description;
                    }
                }
                else {
                    descriptions[name] = description;
                }

            }

            return descriptions;
        }
    }
}