package com.qqchen.deploy.backend.framework.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import java.util.Collections;
import java.util.Map;

/**
 * JSON 工具类
 * <p>提供对象与 JSON、Map 之间的转换功能
 * <p>封装 ObjectMapper，提供统一的异常处理和类型安全的 API
 * <p>基于 Jackson，性能优于 FastJSON2（大型数据集场景下快 1.6 倍）
 *
 * @author qqchen
 * @since 2025-11-06
 */
@Slf4j
@Component
public class JsonUtils {

    @Resource
    private ObjectMapper objectMapper;

    private static ObjectMapper MAPPER;
    
    /**
     * 性能监控阈值（纳秒）：超过 10ms 记录警告日志
     */
    private static final long SLOW_CONVERSION_THRESHOLD_NS = 10_000_000L;

    @PostConstruct
    public void init() {
        MAPPER = this.objectMapper;
        optimizePerformance();
    }
    
    /**
     * 优化 Jackson 性能配置
     */
    private void optimizePerformance() {
        // 1. 反序列化优化：遇到未知属性不抛异常（提升容错性和性能）
        MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        
        // 2. 序列化优化：允许空对象
        MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        
        // 3. 序列化优化：不序列化 null 值字段（减少 JSON 大小，提升性能）
        // 注意：如果业务需要保留 null 字段，可以注释掉这行
        // MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        
        // 4. 日期格式优化：使用 ISO-8601 格式而非时间戳（可读性更好）
        MAPPER.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        
        // 5. 数字格式优化：BigDecimal 作为字符串输出（避免精度丢失）
        MAPPER.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
        
        log.info("JsonUtils 性能优化配置已加载");
    }

    /**
     * 将对象转换为 Map
     * <p>常用于将 DTO 转换为工作流变量
     *
     * @param obj 源对象
     * @return Map，转换失败返回空 Map
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> toMap(Object obj) {
        if (obj == null) {
            return Collections.emptyMap();
        }
        
        try {
            long start = System.nanoTime();
            Map<String, Object> result = MAPPER.convertValue(obj, Map.class);
            logSlowConversion(start, "toMap", obj.getClass().getName());
            return result;
        } catch (Exception e) {
            log.error("对象转换为 Map 失败: {}", obj.getClass().getName(), e);
            return Collections.emptyMap();
        }
    }
    
    /**
     * 将对象转换为 Map（不带性能监控，适用于高频调用场景）
     * <p>性能略优于 toMap()，但不记录慢转换日志
     *
     * @param obj 源对象
     * @return Map，转换失败返回空 Map
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> toMapFast(Object obj) {
        if (obj == null) {
            return Collections.emptyMap();
        }
        
        try {
            return MAPPER.convertValue(obj, Map.class);
        } catch (Exception e) {
            log.error("对象转换为 Map 失败: {}", obj.getClass().getName(), e);
            return Collections.emptyMap();
        }
    }

    /**
     * 将 Map 转换为指定类型的对象
     * <p>常用于将配置 Map 转换为强类型配置对象
     *
     * @param map 源 Map
     * @param clazz 目标类型
     * @param <T> 目标类型
     * @return 转换后的对象，转换失败返回 null
     */
    public static <T> T fromMap(Map<String, Object> map, Class<T> clazz) {
        if (map == null || map.isEmpty()) {
            return null;
        }
        
        try {
            return MAPPER.convertValue(map, clazz);
        } catch (Exception e) {
            log.error("Map 转换为对象失败: {}", clazz.getName(), e);
            return null;
        }
    }

    /**
     * 对象类型转换
     * <p>将一个对象转换为另一个类型（通过 JSON 序列化/反序列化）
     *
     * @param obj 源对象
     * @param clazz 目标类型
     * @param <T> 目标类型
     * @return 转换后的对象，转换失败返回 null
     */
    public static <T> T convert(Object obj, Class<T> clazz) {
        if (obj == null) {
            return null;
        }
        
        try {
            return MAPPER.convertValue(obj, clazz);
        } catch (Exception e) {
            log.error("对象转换失败: {} -> {}", obj.getClass().getName(), clazz.getName(), e);
            return null;
        }
    }

    /**
     * 对象类型转换（支持泛型）
     * <p>用于复杂类型转换，如 List、Map 等
     *
     * @param obj 源对象
     * @param typeReference 目标类型引用
     * @param <T> 目标类型
     * @return 转换后的对象，转换失败返回 null
     */
    public static <T> T convert(Object obj, TypeReference<T> typeReference) {
        if (obj == null) {
            return null;
        }
        
        try {
            return MAPPER.convertValue(obj, typeReference);
        } catch (Exception e) {
            log.error("对象转换失败: {}", obj.getClass().getName(), e);
            return null;
        }
    }

    /**
     * 将对象转换为 JSON 字符串
     *
     * @param obj 源对象
     * @return JSON 字符串，转换失败返回 null
     */
    public static String toJson(Object obj) {
        if (obj == null) {
            return null;
        }
        
        try {
            return MAPPER.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("对象转换为 JSON 失败: {}", obj.getClass().getName(), e);
            return null;
        }
    }

    /**
     * 将对象转换为格式化的 JSON 字符串（带缩进）
     *
     * @param obj 源对象
     * @return 格式化的 JSON 字符串，转换失败返回 null
     */
    public static String toPrettyJson(Object obj) {
        if (obj == null) {
            return null;
        }
        
        try {
            return MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("对象转换为格式化 JSON 失败: {}", obj.getClass().getName(), e);
            return null;
        }
    }

    /**
     * 将 JSON 字符串转换为对象
     *
     * @param json JSON 字符串
     * @param clazz 目标类型
     * @param <T> 目标类型
     * @return 转换后的对象，转换失败返回 null
     */
    public static <T> T fromJson(String json, Class<T> clazz) {
        if (json == null || json.isEmpty()) {
            return null;
        }
        
        try {
            return MAPPER.readValue(json, clazz);
        } catch (JsonProcessingException e) {
            log.error("JSON 转换为对象失败: {}", clazz.getName(), e);
            return null;
        }
    }

    /**
     * 将 JSON 字符串转换为对象（支持泛型）
     *
     * @param json JSON 字符串
     * @param typeReference 目标类型引用
     * @param <T> 目标类型
     * @return 转换后的对象，转换失败返回 null
     */
    public static <T> T fromJson(String json, TypeReference<T> typeReference) {
        if (json == null || json.isEmpty()) {
            return null;
        }
        
        try {
            return MAPPER.readValue(json, typeReference);
        } catch (JsonProcessingException e) {
            log.error("JSON 转换为对象失败", e);
            return null;
        }
    }

    /**
     * 将 JSON 字符串解析为 JsonNode
     *
     * @param json JSON 字符串
     * @return JsonNode，转换失败返回 null
     */
    public static JsonNode parseJson(String json) {
        if (json == null || json.isEmpty()) {
            return null;
        }
        
        try {
            return MAPPER.readTree(json);
        } catch (JsonProcessingException e) {
            log.error("JSON 解析失败", e);
            return null;
        }
    }

    /**
     * 深拷贝对象
     * <p>通过 JSON 序列化/反序列化实现深拷贝
     *
     * @param obj 源对象
     * @param clazz 目标类型
     * @param <T> 目标类型
     * @return 深拷贝后的对象，转换失败返回 null
     */
    public static <T> T deepCopy(T obj, Class<T> clazz) {
        if (obj == null) {
            return null;
        }
        
        try {
            String json = MAPPER.writeValueAsString(obj);
            return MAPPER.readValue(json, clazz);
        } catch (JsonProcessingException e) {
            log.error("对象深拷贝失败: {}", clazz.getName(), e);
            return null;
        }
    }

    /**
     * 判断字符串是否为有效的 JSON
     *
     * @param json JSON 字符串
     * @return true-有效的 JSON，false-无效
     */
    public static boolean isValidJson(String json) {
        if (json == null || json.isEmpty()) {
            return false;
        }
        
        try {
            MAPPER.readTree(json);
            return true;
        } catch (JsonProcessingException e) {
            return false;
        }
    }

    /**
     * 合并两个对象（使用后者覆盖前者的非空字段）
     *
     * @param original 原始对象
     * @param updates 更新对象
     * @param clazz 目标类型
     * @param <T> 目标类型
     * @return 合并后的对象，转换失败返回原始对象
     */
    public static <T> T merge(T original, T updates, Class<T> clazz) {
        if (original == null) {
            return updates;
        }
        if (updates == null) {
            return original;
        }
        
        try {
            return MAPPER.updateValue(original, updates);
        } catch (JsonProcessingException e) {
            log.error("对象合并失败: {}", clazz.getName(), e);
            return original;
        }
    }
    
    // ==================== 性能监控辅助方法 ====================
    
    /**
     * 记录慢转换日志
     * <p>当转换耗时超过阈值时记录警告日志
     *
     * @param startTimeNs 开始时间（纳秒）
     * @param operation 操作名称
     * @param target 目标类型
     */
    private static void logSlowConversion(long startTimeNs, String operation, String target) {
        long duration = System.nanoTime() - startTimeNs;
        if (duration > SLOW_CONVERSION_THRESHOLD_NS) {
            double durationMs = duration / 1_000_000.0;
            log.warn("JSON 转换耗时过长: operation={}, target={}, duration={}ms", 
                    operation, target, String.format("%.2f", durationMs));
        }
    }
    
    // ==================== 便捷工具方法 ====================
    
    /**
     * 获取 ObjectMapper 实例（用于高级定制场景）
     * <p>注意：直接使用 ObjectMapper 会绕过工具类的统一异常处理和性能监控
     *
     * @return ObjectMapper 实例
     */
    public static ObjectMapper getMapper() {
        return MAPPER;
    }
    
    /**
     * 判断对象是否可以被 JSON 序列化
     *
     * @param obj 源对象
     * @return true-可序列化，false-不可序列化
     */
    public static boolean isSerializable(Object obj) {
        if (obj == null) {
            return true;
        }
        
        try {
            MAPPER.writeValueAsString(obj);
            return true;
        } catch (Exception e) {
            log.debug("对象不可序列化: {}", obj.getClass().getName());
            return false;
        }
    }
    
    /**
     * 格式化 JSON 字符串（美化输出）
     * <p>适用于日志输出、调试等场景
     *
     * @param json JSON 字符串
     * @return 格式化后的 JSON 字符串，格式化失败返回原字符串
     */
    public static String prettyFormat(String json) {
        if (json == null || json.isEmpty()) {
            return json;
        }
        
        try {
            Object obj = MAPPER.readValue(json, Object.class);
            return MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.debug("JSON 格式化失败，返回原字符串", e);
            return json;
        }
    }
    
    /**
     * 压缩 JSON 字符串（移除所有空白字符）
     * <p>适用于网络传输、存储等场景
     *
     * @param json JSON 字符串
     * @return 压缩后的 JSON 字符串，压缩失败返回原字符串
     */
    public static String compactFormat(String json) {
        if (json == null || json.isEmpty()) {
            return json;
        }
        
        try {
            Object obj = MAPPER.readValue(json, Object.class);
            return MAPPER.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.debug("JSON 压缩失败，返回原字符串", e);
            return json;
        }
    }
}

