using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;

namespace SHH.CameraService
{
    /// <summary>
    /// JSON 序列化与反序列化帮助类
    /// 职责：
    /// 1.  提供全局统一的 JSON 转换配置（如驼峰命名、日期格式）。
    /// 2.  封装常见的序列化和反序列化操作。
    /// 3.  增加对 null 输入和无效 JSON 的健壮性处理。
    /// </summary>
    public static class JsonHelper
    {
        #region --- 静态配置 ---

        /// <summary>
        /// 全局共享的 JSON 序列化设置。
        /// 静态构造函数保证其只被初始化一次。
        /// </summary>
        private static readonly JsonSerializerSettings _settings;

        #endregion

        #region --- 静态构造函数 ---

        /// <summary>
        /// 静态构造函数，用于初始化全局的 JSON 序列化设置。
        /// </summary>
        static JsonHelper()
        {
            _settings = new JsonSerializerSettings
            {
                // 1. 命名策略：将 C# 的 PascalCase 属性名序列化为 JSON 的 camelCase。
                //    这是与 JavaScript/TypeScript 前端交互的标准做法。
                ContractResolver = new CamelCasePropertyNamesContractResolver(),

                // 2. 日期格式：统一使用 "yyyy-MM-dd HH:mm:ss" 格式，避免时区和格式差异导致的问题。
                DateFormatString = "yyyy-MM-dd HH:mm:ss",

                // 3. Null 值处理：在序列化时忽略值为 null 的属性。
                //    这可以显著减小 JSON 字符串的大小，并使生成的 JSON 更干净。
                //    例如，`{ Name = "Alice", Age = null }` 会被序列化为 `{"name":"Alice"}`。
                NullValueHandling = NullValueHandling.Ignore
            };

            // 4. 枚举转换：将枚举值序列化为其字符串表示，而不是数字。
            //    例如，`LogLevel.Info` 会被序列化为 `"info"`，而不是 `1`。
            _settings.Converters.Add(new StringEnumConverter());
        }

        #endregion

        #region --- 公共方法 ---

        /// <summary>
        /// 将对象序列化为 JSON 字符串。
        /// </summary>
        /// <param name="obj">要序列化的对象。</param>
        /// <returns>序列化后的 JSON 字符串。如果输入为 null，则返回空字符串。</returns>
        public static string Serialize(object obj)
        {
            // [健壮性] 如果输入对象为 null，返回空字符串，而不是 "null"。
            // 这可以防止在创建 HTTP 请求内容时出现意外行为。
            if (obj == null)
            {
                return string.Empty;
            }

            return JsonConvert.SerializeObject(obj, _settings);
        }

        /// <summary>
        /// 将 JSON 字符串反序列化为指定类型的对象。
        /// </summary>
        /// <typeparam name="T">目标对象的类型（必须是引用类型）。</typeparam>
        /// <param name="json">要反序列化的 JSON 字符串。</param>
        /// <returns>成功时返回反序列化后的对象；失败或输入无效时返回 null。</returns>
        public static T? Deserialize<T>(string json) where T : class
        {
            // [健壮性] 检查输入是否为 null、空字符串或仅包含空白字符。
            if (string.IsNullOrWhiteSpace(json))
            {
                return null;
            }

            // [健壮性] 处理 JSON 字符串为 "null" 的特殊情况。
            if (json.Trim() == "null")
            {
                return null;
            }

            try
            {
                // 尝试使用预配置的设置进行反序列化。
                return JsonConvert.DeserializeObject<T>(json, _settings);
            }
            catch (JsonException)
            {
                // [健壮性] 如果 JSON 格式无效，捕获异常并返回 null。
                // 这可以防止程序因一个格式错误的 JSON 字符串而崩溃。
                return null;
            }
        }

        #endregion
    }
}