using System;
using System.Collections.Generic;
using System.Reflection;
using Newtonsoft.Json;

namespace QYZH.InteractiveMagazine.Common.Extensions
{
    /// <summary>
    /// 对象扩展方法
    /// </summary>
    public static class ObjectExtension
    {
        /// <summary>
        /// 将源对象的属性值拷贝到目标对象
        /// </summary>
        /// <typeparam name="T">目标对象类型</typeparam>
        /// <param name="source">源对象</param>
        /// <param name="target">目标对象</param>
        /// <returns>目标对象</returns>
        public static T CopyTo<T>(this object source, T target)
        {
            if (source == null || target == null)
            {
                return target;
            }

            Type sourceType = source.GetType();
            Type targetType = target.GetType();

            PropertyInfo[] sourceProperties = sourceType.GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (PropertyInfo sourceProp in sourceProperties)
            {
                if (!sourceProp.CanRead)
                {
                    continue;
                }

                PropertyInfo? targetProp = targetType.GetProperty(sourceProp.Name);

                if (targetProp != null && targetProp.CanWrite &&
                    targetProp.PropertyType == sourceProp.PropertyType)
                {
                    object? value = sourceProp.GetValue(source);
                    targetProp.SetValue(target, value);
                }
            }

            return target;
        }

        /// <summary>
        /// 将对象转换为JSON字符串
        /// </summary>
        /// <param name="obj">对象</param>
        /// <param name="formatting">格式化选项</param>
        /// <returns>JSON字符串</returns>
        public static string ToJson(this object obj, Formatting formatting = Formatting.None)
        {
            if (obj == null)
            {
                return string.Empty;
            }

            return JsonConvert.SerializeObject(obj, formatting);
        }

        /// <summary>
        /// 将对象转换为字典
        /// </summary>
        /// <param name="obj">对象</param>
        /// <returns>字典</returns>
        public static Dictionary<string, object?> ToDictionary(this object obj)
        {
            if (obj == null)
            {
                return new Dictionary<string, object?>();
            }

            var dictionary = new Dictionary<string, object?>();
            PropertyInfo[] properties = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (PropertyInfo property in properties)
            {
                if (property.CanRead)
                {
                    dictionary[property.Name] = property.GetValue(obj);
                }
            }

            return dictionary;
        }

        public static bool IsNull<T>(this IList<T>? s)
        {
            return s == null || s?.Count() < 1;
        }

        public static bool IsNull(this object? s)
        {
            return s == null;
        }
    }
}
