using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Reflection;

namespace IRaCIS.Core.Infrastructure.Extention
{
    public static class ObjectExtension
    {

        public static T Clone<T>(this T source)
        {
            // Don't serialize a null object, simply return the default for that object
            if (Object.ReferenceEquals(source, null))
            {
                return default(T);
            }

            var deserializeSettings = new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace };
            var serializeSettings = new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
            return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source, serializeSettings), deserializeSettings);
        }

        /// <summary>
        /// 将对象序列化成稽查需要的Json字符串
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ToJsonStr(this object obj)
        {

            return JsonConvert.SerializeObject(obj, new JsonSerializerSettings { DateFormatString = "yyyy-MM-dd HH:mm:ss", ReferenceLoopHandling = ReferenceLoopHandling.Ignore, NullValueHandling = NullValueHandling.Ignore });
        }

        /// <summary>
        /// 通过类型参数反序列化 JSON 字符串为指定类型的对象
        /// </summary>
        /// <param name="jsonStr"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static object JsonStrToObject(this string jsonStr, Type type)
        {
            return JsonConvert.DeserializeObject(jsonStr, type);
        }


        public static Dictionary<string, object> ToDictionary(this object obj)
        {
            var json = JsonConvert.SerializeObject(obj, new JsonSerializerSettings { DateFormatString = "yyyy-MM-dd HH:mm:ss", Formatting = Formatting.Indented, ReferenceLoopHandling = ReferenceLoopHandling.Ignore, NullValueHandling = NullValueHandling.Include });
            return JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
        }
        /// <summary>
        /// 将对象序列化成稽查需要的Json字符串
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ToJsonNotIgnoreNull(this object obj)
        {

            return JsonConvert.SerializeObject(obj, new JsonSerializerSettings { DateFormatString = "yyyy-MM-dd HH:mm:ss", Formatting = Formatting.Indented, ReferenceLoopHandling = ReferenceLoopHandling.Ignore, NullValueHandling = NullValueHandling.Include });
        }

        public static Dictionary<string, object> ConvertToDictionary(this object obj)
        {
            if (obj == null)
            {
                throw new ArgumentNullException(nameof(obj));
            }

            Type type = obj.GetType();
            PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);

            Dictionary<string, object> dictionary = new Dictionary<string, object>();

            foreach (PropertyInfo property in properties)
            {
                string propertyName = property.Name;
                object propertyValue = property.GetValue(obj);
                // 如果属性的类型是枚举,将其值保留为整数
                if (property.PropertyType.IsEnum || (Nullable.GetUnderlyingType(property.PropertyType)?.IsEnum == true && propertyValue != null))
                {
                    dictionary.Add(propertyName, (int)propertyValue);
                }
                // 检查属性是否是时间类型
                else if (property.PropertyType == typeof(DateTime) ||
                     property.PropertyType == typeof(DateTime?) && propertyValue != null)
                {
                    DateTime.TryParse(propertyValue.ToString(), out DateTime result);
                    var dt = ExportExcelConverterDate.DateTimeInternationalToString(result);
                    // 如果需要,可以对时间值进行特定的处理
                    dictionary.Add(propertyName, dt);
                }
                else
                {
                    dictionary.Add(propertyName, propertyValue);
                }
            }

            return dictionary;
        }
    }
}