package org.example.Utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.NullNode;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
// 正确导入：Jackson 核心包的 ObjectMapper
import com.fasterxml.jackson.databind.ObjectMapper;
// 同时确保导入其他依赖的类（避免连锁错误）
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.JsonDeserializer;

import java.io.IOException;
import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.TimeZone;

/**
 * Jackson 实现的 JSON 工具类，完全替代原 Gson 版本，保持与 C# JSON 方法一致的功能
 */
public class JSON {
    private static final Logger log = LoggerFactory.getLogger(JSON.class);

    private static boolean defaultSetting = false;
    public static String dateTimeFormat = "yyyy-MM-dd HH:mm:ss";
    // Jackson 核心对象映射器（全局单例，线程安全）
    private static final ObjectMapper objectMapper;
    private static final Object NULL_PLACEHOLDER = "null";
    // ------------------------------
    // 1. 自定义序列化器：适配原 Gson 逻辑
    // ------------------------------

    /**
     * 日期序列化器：将 Date 转为 "yyyy-MM-dd HH:mm:ss"（东八区），对应原 DateTimeSerializer
     */
    private static class DateTimeSerializer extends JsonSerializer<Date> {
        private final SimpleDateFormat sdf = new SimpleDateFormat(dateTimeFormat);

        {
            sdf.setTimeZone(TimeZone.getTimeZone("GMT+8")); // 明确东八区，与原逻辑一致
        }

        @Override
        public void serialize(Date date, JsonGenerator gen, SerializerProvider provider) throws IOException {
            gen.writeString(sdf.format(date));
        }
    }

    /**
     * 字符串序列化器：空字符串/Null 按 Null 处理（后续会被过滤），对应原 TypeAdapter<String>
     */
    private static class StringSerializer extends JsonSerializer<String> {
        @Override
        public void serialize(String value, JsonGenerator gen, SerializerProvider provider) throws IOException {
            if (value == null) {
                gen.writeNull();
                return;
            }
            // 空字符串正常输出（符合你的需求）
            gen.writeString(value);
        }
    }


    /**
     * 集合序列化器：空集合/Null 按 Null 处理（后续会被过滤），对应原 TypeAdapter<Collection>
     */
    private static class CollectionSerializer extends JsonSerializer<Collection<?>> {
        @Override
        public void serialize(Collection<?> collection, JsonGenerator gen, SerializerProvider provider) throws IOException {
            if (collection == null) {
                gen.writeNull(); // 仅 null 集合写 null（配合全局 NON_NULL 会被过滤）
                return;
            }
            // ！！删除空集合写 null 的逻辑！！空集合直接走正常数组序列化
            gen.writeStartArray();
            for (Object elem : collection) {
                if (elem != null) { // 保留原逻辑：过滤集合中的 null 元素
                    objectMapper.writeValue(gen, elem);
                }
            }
            gen.writeEndArray();
        }
    }

    // ------------------------------
    // 1. 自定义序列化器：新增 MapSerializer（过滤 Map 中的 null 值）
    // ------------------------------
    private static class MapSerializer extends JsonSerializer<Map<?, ?>> {
        @Override
        public void serialize(Map<?, ?> map, JsonGenerator gen, SerializerProvider provider) throws IOException {
            if (map == null) {
                gen.writeNull(); // 配合全局 NON_NULL 过滤 null Map
                return;
            }
            gen.writeStartObject();
            // 遍历 Map，仅序列化 value 非 null 的键值对
            for (Map.Entry<?, ?> entry : map.entrySet()) {
                Object key = entry.getKey();
                Object value = entry.getValue();
                if (value != null) { // 跳过 value 为 null 的项
                    gen.writeFieldName(key.toString()); // 写键
                    objectMapper.writeValue(gen, value); // 递归序列化值（兼容嵌套类型）
                }
            }
            gen.writeEndObject();
        }
    }

    /**
     * 字符串反序列化器：对应原 TypeAdapter<String> 的 read 方法
     */
    private static class StringDeserializer extends JsonDeserializer<String> {
        @Override
        public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
            return p.getText(); // 直接读取字符串，与原逻辑一致
        }
    }

    // ------------------------------
    // 2. 初始化 ObjectMapper：复刻原 Gson 所有配置
    // ------------------------------
    static {
        JsonFactory jsonFactory = new JsonFactory();
        jsonFactory.configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, false);

        objectMapper = new ObjectMapper(jsonFactory);
        SimpleModule customModule = new SimpleModule("CustomModule");

        // 1. 注册独立的 StringSerializer（不再用匿名内部类，逻辑正确）
        customModule.addSerializer(String.class, new StringSerializer());

        // 2. 注册独立的 CollectionSerializer（逻辑正确）
        @SuppressWarnings("unchecked")
        Class<? extends Collection<?>> collectionType = (Class<? extends Collection<?>>) (Class<?>) Collection.class;
        customModule.addSerializer(collectionType, new CollectionSerializer());

        @SuppressWarnings("unchecked")
        Class<? extends Map<?, ?>> mapType = (Class<? extends Map<?, ?>>) (Class<?>) Map.class;
        customModule.addSerializer(mapType, new MapSerializer());

        // 3. 其他序列化器（不变）
        customModule.addSerializer(Date.class, new DateTimeSerializer());
        customModule.addDeserializer(String.class, new StringDeserializer());
        customModule.addSerializer(Long.class, ToStringSerializer.instance);
        customModule.addSerializer(Long.TYPE, ToStringSerializer.instance);

        // 4. 全局配置（不变，确保 NON_NULL 生效）
        objectMapper
                .registerModule(customModule)
                .setSerializationInclusion(JsonInclude.Include.NON_NULL) // 核心：忽略所有 null 字段
                .configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false) // 忽略 Map 中的 null 值
                .configure(SerializationFeature.FAIL_ON_SELF_REFERENCES, false)
                .configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, true) // 保留空数组
                .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
                .enable(SerializationFeature.INDENT_OUTPUT)
                .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    }

    // ------------------------------
    // 3. 保持原 C# 风格的默认配置方法（空实现，仅为兼容原代码结构）
    // ------------------------------
    private static void defaultSetting() {
        if (defaultSetting) return;
        defaultSetting = true;
        // Jackson 配置已在静态块初始化，此处保持与原 C# 方法结构一致
    }

    // ------------------------------
    // 4. 核心 API：与原 Gson 工具类方法名、功能完全一致
    // ------------------------------

    /**
     * 获取全局 ObjectMapper 实例（支持自定义扩展）
     */
    public static ObjectMapper getObjectMapper() {
        return objectMapper;
    }

    /**
     * 序列化：将对象转为 JSON 字符串，对应原 toJson()
     */
    public static String toJson(Object obj) {
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("Exception caught", e);
            return null;
        }
    }

    /**
     * 反序列化：将 JSON 转为指定类型对象，对应原 fromJson(Class<T>)
     */
    public static <T> T fromJson(String json, Class<T> clazz) {
        if (json == null || json.isEmpty()) {
            return null;
        }
        try {
            return objectMapper.readValue(json, clazz);
        } catch (JsonProcessingException e) {
            log.error("Exception caught", e);
            return null;
        }
    }

    /**
     * 反序列化：将 JSON 转为指定泛型类型（如 List<T>、Map<K,V>），对应原 fromJson(Type)
     */
    public static <T> T fromJson(String json, Type type) {
        if (json == null || json.isEmpty()) {
            return null;
        }
        // Jackson 用 TypeReference 接收泛型类型，需转换 Type 为 TypeReference
        TypeReference<T> typeRef = new TypeReference<T>() {
            @Override
            public Type getType() {
                return type;
            }
        };
        try {
            return objectMapper.readValue(json, typeRef);
        } catch (JsonProcessingException e) {
            log.error("Exception caught", e);
            return null;
        }
    }

    // ------------------------------
    // 5. C# 风格方法：Encode/Decode，保持原逻辑完全一致
    // ------------------------------

    /**
     * 等效于 C# 的 JSON.Encode()：处理 String 类型特殊逻辑，其他类型正常序列化
     */
    public static String Encode(Object o) {
        defaultSetting(); // 兼容原 C# 方法的默认配置调用
        if (o == null) {
            return null;
        }
        if ("null".equals(o.toString().trim())) {
            return null;
        }
        if (o instanceof String) {
            return (String) o;
        }
        return toJson(o);
    }

    /**
     * 等效于 C# 的 JSON.Decode(string json)：将 JSON 转为 Java 原生集合（Hashtable/ArrayList）
     */
    public static Object Decode(String json) {
        if (json == null || json.isEmpty()) {
            return "";
        }
        try {
            // 第一步：解析 JSON 为 JsonNode（Jackson 的 JSON 节点模型）
            JsonNode rootNode = objectMapper.readTree(json);
            // 第二步：若解析结果是字符串，尝试二次解析（复刻原 Gson 逻辑）
            if (rootNode.isTextual()) {
                String strValue = rootNode.asText();
                rootNode = objectMapper.readTree(strValue); // 二次解析字符串中的 JSON
            }
            // 第三步：递归转为 Java 原生集合（Hashtable/ArrayList），与原 toObject() 逻辑一致
            return toObject(rootNode);
        } catch (Exception e) {
            log.error("Exception caught", e);
            return null;
        }
    }

    /**
     * 等效于 C# 的 JSON.Decode(string json, Type type)：指定类型反序列化
     */
    public static Object Decode(String json, Type type) {
        if (json == null || json.isEmpty()) {
            return null;
        }
        // 复用 fromJson(Type) 逻辑，保持一致
        return fromJson(json, type);
    }

    // ------------------------------
    // 6. 辅助方法：复刻原 toObject() 逻辑，将 JsonNode 转为 Java 原生集合
    // ------------------------------

    /**
     * 递归转换 JsonNode 为 Java 原生对象（Hashtable/ArrayList/基本类型），与原 Gson 逻辑完全一致
     */
    public static Object toObject(JsonNode node) {
        if (node == null || node.isNull() || node instanceof NullNode) {
            return NULL_PLACEHOLDER;
        }

        // 处理基本类型（字符串、数字、布尔）
        if (node.isValueNode()) {
            if (node.isTextual()) {
                String s = node.asText();
                // 处理特殊日期格式（2010-09-02T10:00:00），复刻原 Gson 逻辑
                if (s.length() == 19 && s.charAt(10) == 'T'
                        && s.charAt(4) == '-' && s.charAt(13) == ':') {
                    try {
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
                        return sdf.parse(s);
                    } catch (ParseException e) {
                        return s; // 解析失败则返回原字符串
                    }
                }
                return s;
            } else if (node.isNumber()) {
                return node.numberValue(); // 数字→Number（自动适配 int/long/double）
            } else if (node.isBoolean()) {
                return node.booleanValue(); // 布尔→Boolean
            }
        }

        // 处理 JSON 对象→Hashtable（与原 Gson 逻辑一致，不用 HashMap 是为了兼容 C# 的 Dictionary）
        if (node.isObject()) {
            Hashtable<String, Object> hashtable = new Hashtable<>();
            Iterator<Map.Entry<String, JsonNode>> fields = node.fields();
            while (fields.hasNext()) {
                Map.Entry<String, JsonNode> entry = fields.next();
                hashtable.put(entry.getKey(), toObject(entry.getValue())); // 递归转换子节点
            }
            return hashtable;
        }

        // 处理 JSON 数组→ArrayList（与原 Gson 逻辑一致）
        if (node.isArray()) {
            ArrayList<Object> list = new ArrayList<>(node.size());
            for (JsonNode itemNode : node) {
                list.add(toObject(itemNode)); // 递归转换数组元素
            }
            return list;
        }

        // 5. 兜底：所有未匹配的场景返回空字符串（不再返回null）
        return NULL_PLACEHOLDER;
    }
}

