using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json.Serialization;
using System.Text.Json;
using System.Threading.Tasks;

namespace JiShe.CollectBus.Common.Helpers
{
    /// <summary>
    /// json帮助类
    /// </summary>
    public static class BusJsonSerializer
    {
        /// <summary>
        /// json对象转换成字符串
        /// </summary>
        /// <param name="obj">需要序列化的对象</param>
        /// <param name="IsIgnore">是否忽略实体中实体，不再序列化里面包含的实体</param>
        /// <param name="jsonSerializerOptions">配置</param>
        /// <returns></returns>
        public static string Serialize(this object obj, bool IsIgnore = false, JsonSerializerOptions jsonSerializerOptions = null)
        {
            if (jsonSerializerOptions == null)
            {
                jsonSerializerOptions = new JsonSerializerOptions
                {
                    DefaultIgnoreCondition = JsonIgnoreCondition.Never,
                    WriteIndented = false,// 设置格式化输出
                    Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,// 允许特殊字符
                    IgnoreReadOnlyFields = true,
                    IgnoreReadOnlyProperties = true,
                    NumberHandling = JsonNumberHandling.AllowReadingFromString, // 允许数字字符串
                    AllowTrailingCommas = true, // 忽略尾随逗号
                    ReadCommentHandling = JsonCommentHandling.Skip, // 忽略注释
                    PropertyNameCaseInsensitive = true, // 属性名称大小写不敏感
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase, // 属性名称使用驼峰命名规则
                    Converters = { new DateTimeJsonConverter() }, // 注册你的自定义转换器, 
                    DefaultBufferSize = 4096,
                };
            }

            if (IsIgnore == true)
            {
                jsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles; // 忽略循环引用

                return JsonSerializer.Serialize(obj, jsonSerializerOptions);
            }
            else
            {
                return JsonSerializer.Serialize(obj, jsonSerializerOptions);
            }
        }

        /// <summary>
        /// json字符串转换成json对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="json"></param>
        /// <param name="IsIgnore">是否忽略实体中实体，不再序列化里面包含的实体</param>
        /// <param name="jsonSerializerOptions">配置</param>
        /// <returns></returns>
        public static T? Deserialize<T>(this string json, bool IsIgnore = false, JsonSerializerOptions jsonSerializerOptions = null)
        {
            if (jsonSerializerOptions == null)
            {
                jsonSerializerOptions = new JsonSerializerOptions
                {
                    DefaultIgnoreCondition = JsonIgnoreCondition.Never,
                    WriteIndented = false,// 设置格式化输出
                    Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,// 允许特殊字符
                    IgnoreReadOnlyFields = true,
                    IgnoreReadOnlyProperties = true,
                    NumberHandling = JsonNumberHandling.AllowReadingFromString, // 允许数字字符串
                    AllowTrailingCommas = true, // 忽略尾随逗号
                    ReadCommentHandling = JsonCommentHandling.Skip, // 忽略注释
                    PropertyNameCaseInsensitive = true, // 属性名称大小写不敏感
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase, // 属性名称使用驼峰命名规则
                    Converters = { new DateTimeJsonConverter() }, // 注册你的自定义转换器, 
                    DefaultBufferSize = 4096,
                };
            }

            if (IsIgnore == true)
            {
                jsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles; // 忽略循环引用

                return json == null ? default(T) : JsonSerializer.Deserialize<T>(json, jsonSerializerOptions);
            }
            else
            {
                return json == null ? default(T) : JsonSerializer.Deserialize<T>(json, jsonSerializerOptions);
            }
        }

        /// <summary>
        /// json字符串转换成json对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="json"></param>
        /// <param name="IsIgnore">是否忽略实体中实体，不再序列化里面包含的实体</param>
        /// <param name="jsonSerializerOptions">配置</param>
        /// <returns></returns>
        public static object? Deserialize(this string json, Type type, bool IsIgnore = false, JsonSerializerOptions jsonSerializerOptions = null)
        {
            if (jsonSerializerOptions == null)
            {
                jsonSerializerOptions = new JsonSerializerOptions
                {
                    DefaultIgnoreCondition = JsonIgnoreCondition.Never,
                    WriteIndented = false,// 设置格式化输出
                    Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,// 允许特殊字符
                    IgnoreReadOnlyFields = true,
                    IgnoreReadOnlyProperties = true,
                    NumberHandling = JsonNumberHandling.AllowReadingFromString, // 允许数字字符串
                    AllowTrailingCommas = true, // 忽略尾随逗号
                    ReadCommentHandling = JsonCommentHandling.Skip, // 忽略注释
                    PropertyNameCaseInsensitive = true, // 属性名称大小写不敏感
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase, // 属性名称使用驼峰命名规则
                    Converters = { new DateTimeJsonConverter() } // 注册你的自定义转换器, 
                };
            }

            

            if (IsIgnore == true)
            {
                jsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles; // 忽略循环引用

                return json == null ? null : JsonSerializer.Deserialize(json, type, jsonSerializerOptions);
            }
            else
            {
                return json == null ? null : JsonSerializer.Deserialize(json, type, jsonSerializerOptions);
            }
        }

        /// <summary>
        /// list json字符串转换成list 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="json"></param>
        /// <returns></returns>
        public static List<T>? DeserializeToList<T>(this string json)
        {
            return json == null ? default(List<T>) : Deserialize<List<T>>(json);
        }
    }


    public class DateTimeJsonConverter : JsonConverter<DateTime>
    {
        private readonly string _dateFormatString;
        public DateTimeJsonConverter()
        {
            _dateFormatString = "yyyy-MM-dd HH:mm:ss";
        }

        public DateTimeJsonConverter(string dateFormatString)
        {
            _dateFormatString = dateFormatString;
        }

        public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            return DateTime.Parse(reader.GetString());
        }

        public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
        {
            writer.WriteStringValue(value.ToString(_dateFormatString));
        }
    }

    /// <summary>
    /// Unix格式时间格式化
    /// </summary>
    public class UnixTimeConverter : JsonConverter<DateTime>
    {
        public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            if (reader.TokenType == JsonTokenType.String)
            {
                if (long.TryParse(reader.GetString(), out long timestamp))
                    return DateTimeOffset.FromUnixTimeSeconds(timestamp).DateTime;
            }

            if (reader.TokenType == JsonTokenType.Number)
            {
                long timestamp = reader.GetInt64();
                return DateTimeOffset.FromUnixTimeSeconds(timestamp).DateTime;
            }
            return reader.GetDateTime();
        }

        public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
        {
            long timestamp = new DateTimeOffset(value).ToUnixTimeSeconds();
            writer.WriteStringValue(timestamp.ToString());
        }
    }
}
