using System.ComponentModel;
using System.Reflection;
using System;
using System.Text.RegularExpressions;

namespace JiaZhiQuan.Common.Utils
{
    public static class ObjectUtils
    {

        /// <summary>
        /// 将一个对象转换为指定类型
        /// </summary>
        /// <param name="obj">待转换的对象</param>
        /// <param name="type">目标类型</param>
        /// <returns>转换后的对象</returns>
        public static object ConvertObjectToType(object obj, Type type)
        {
            if (type == null) return obj;
            if (obj == null) return type.IsValueType ? Activator.CreateInstance(type) : null;

            // 如果目标类型为可空类型，则取可空类型的基类型.
            // case: int? -> int, DateTime? -> DateTime
            Type underlyingType = Nullable.GetUnderlyingType(type);
            // 如果待转换对象的类型与目标类型兼容，则无需转换
            // case: string -> string, int -> int, int -> object, int? -> int?, int? -> object
            if (type.IsAssignableFrom(obj.GetType()))
            {
                return obj;
            }
            // 如果待转换的对象的基类型为枚举
            else if ((underlyingType ?? type).IsEnum)
            {
                // 如果目标类型为可空枚举，且待转换对象为空字符串，则返回null
                if (underlyingType != null && string.IsNullOrEmpty(obj.ToString()))
                {
                    return null;
                }
                else
                {
                    // 如果目标类型为可空枚举，且待转换对象不为空字符串，则先将其转换为基类型的枚举，再转换为可空枚举
                    return Enum.Parse(underlyingType ?? type, obj.ToString());
                }
            }
            // 如果目标类型为可转换类型
            else if (typeof(IConvertible).IsAssignableFrom(underlyingType ?? type))
            {
                try
                {
                    // 将待转换对象转换为目标类型
                    return Convert.ChangeType(obj, underlyingType ?? type);
                }
                catch
                {
                    return underlyingType == null ? Activator.CreateInstance(type) : null;
                }
            }
            else
            {
                // 获取类型转换器
                TypeConverter converter = TypeDescriptor.GetConverter(type);
                // 判断是否支持从待转换对象类型到目标类型的转换
                if (converter.CanConvertFrom(obj.GetType()))
                {
                    // 转换类型并返回
                    return converter.ConvertFrom(obj);
                }
                ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);
                if (constructor != null)
                {
                    object o = constructor.Invoke(null);
                    PropertyInfo[] propertys = type.GetProperties();
                    Type oldType = obj.GetType();
                    foreach (PropertyInfo property in propertys)
                    {
                        PropertyInfo p = oldType.GetProperty(property.Name);
                        if (property.CanWrite && p != null && p.CanRead)
                        {
                            property.SetValue(o, ConvertObjectToType(p.GetValue(obj, null), property.PropertyType), null);
                        }
                    }
                    return o;
                }
            }
            return obj;
        }

        private const int baseValue = 34;
        private const string digits = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ";

        /// <summary>
        /// long转换为34进制
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        public static string ConvertToBase34(this long number)
        {
            if (number == 0)
                return "0";

            string result = string.Empty;

            while (number != 0)
            {
                int remainder = (int)(number % baseValue);
                result = digits[remainder] + result;
                number /= baseValue;
            }

            return result;
        }
        /// <summary>
        /// 手机号码验证
        /// </summary>
        /// <param name="phoneNumber"></param>
        /// <returns></returns>
        public static bool IsPhoneNumber(string phoneNumber) {
            if(string.IsNullOrEmpty(phoneNumber)) return false;
            // 正则表达式模式，用于验证手机号码
            string pattern = @"^1[3-9]\d{9}$";
            Regex regex = new Regex(pattern);
            return regex.IsMatch(phoneNumber);
        }

        /// <summary>
        /// 34进制字符串转long
        /// </summary>
        /// <param name="base34"></param>
        /// <returns></returns>
        public static long ConvertFromBase34(this string base34)
        {
            if (base34 == "0")
                return 0;

            long result = 0;
            int power = 0;

            for (int i = base34.Length - 1; i >= 0; i--)
            {
                int digitValue = digits.IndexOf(base34[i]);
                result += digitValue * (long)Math.Pow(baseValue, power);
                power++;
            }

            return result;
        }

    }
}
