using Newtonsoft.Json;
using System;
using System.Reflection;
using System.Text.RegularExpressions;

namespace AutoTurnOver.Utility
{
    public static class JsonHelper
    {
        /// <summary>
        /// 格式化字符串
        /// </summary>
        public static string FormateStr
        {
            get;
            set;
        }
        public static string ToJson(this object obj, bool hasTime = false)
        {
            //JsonSerializerSettings jss = new JsonSerializerSettings();
            string jsonString = JsonConvert.SerializeObject(obj); 
            string p = @"\\/Date\((\d+)\)\\/";
            MatchEvaluator matchEvaluator = null;
            if (hasTime)
            {
                matchEvaluator = new MatchEvaluator(ConvertJsonDateToDateString2);
            }
            else
            {
                matchEvaluator = new MatchEvaluator(ConvertJsonDateToDateString);
            }

            Regex reg = new Regex(p);
            jsonString = reg.Replace(jsonString, matchEvaluator);
            return jsonString;
        }

        /// <summary>  
        /// 将Json序列化的时间由/Date(1294499956278)转为字符串 .
        /// </summary>  
        /// <param name="m">正则匹配</param>
        /// <returns>格式化后的字符串</returns>
        private static string ConvertJsonDateToDateString(Match m)
        {
            string result = string.Empty;
            DateTime dt = new DateTime(1970, 1, 1);
            dt = dt.AddMilliseconds(long.Parse(m.Groups[1].Value));
            dt = dt.ToLocalTime();
            result = dt.ToString("yyyy-MM-dd");
            return result;
        }

        /// <summary>  
        /// 将Json序列化的时间由/Date(1294499956278)转为字符串 .
        /// </summary>  
        /// <param name="m">正则匹配</param>
        /// <returns>格式化后的字符串</returns>
        private static string ConvertJsonDateToDateString2(Match m)
        {
            string result = string.Empty;
            DateTime dt = new DateTime(1970, 1, 1);
            dt = dt.AddMilliseconds(long.Parse(m.Groups[1].Value));
            dt = dt.ToLocalTime();
            result = dt.ToString("yyyy-MM-dd HH:mm:ss");
            return result;
        }

        public static T ToObj<T>(this string objStr)
        {
            return JsonConvert.DeserializeObject<T>(objStr);
        }

        /// <summary>
        /// 判断对象是否完全相同
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool MyEquals(this object obj, object obj2)
        {
            bool equals = true;
            if (obj == null || obj2 == null) return true;
            Type ts = obj.GetType();
            Type ts2 = obj2.GetType();
            if (ts != ts2) return false;
            foreach (var item in ts.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
            {
                //检查对象二是否有该属性
                var item2 = ts2.GetProperty(item.Name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
                if (item2 == null) return false;
                //判断是不是引用类型
                var itemValue = item.GetValue(obj);
                var item2Value = item2.GetValue(obj2);
                if (itemValue == null && item2Value != null) return false;
                if (item2Value == null && itemValue != null) return false;
                if (itemValue == null && item2Value == null) { continue; }
                if (itemValue.GetType() == typeof(DateTime))
                {
                    //值类型,直接判断是否相等
                    if ((DateTime.Parse(itemValue.ToString()) - DateTime.Parse(item2Value.ToString())).Ticks != 0) return false;
                }
                else if (itemValue.GetType().IsValueType || itemValue.GetType() == typeof(string))
                {
                    //值类型,直接判断是否相等
                    if (!itemValue.Equals(item2Value)) return false;
                }
                else
                {
                    //引用类型
                    if (!itemValue.MyEquals(item2Value)) return false;
                }
            }

            return equals;
        }
    }
}
