package com.gzzm.lobster.common;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import java.util.Collections;
import java.util.Map;

/**
 * 统一 JSON 序列化工具 / Centralized JSON (de)serialization.
 *
 * <p>用 Jackson 单例 ObjectMapper，统一配置：不输出 null 字段、忽略未知字段、
 * 时间走 ISO-8601。
 * Uses a Jackson singleton with: omit nulls, ignore unknown props, ISO-8601 dates.
 */
public final class JsonUtil {

    private static final ObjectMapper MAPPER = new ObjectMapper()
            .registerModule(new JavaTimeModule())
            .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
            .setSerializationInclusion(JsonInclude.Include.NON_NULL);

    private JsonUtil() {}

    public static ObjectMapper mapper() { return MAPPER; }

    public static String toJson(Object o) {
        try {
            return MAPPER.writeValueAsString(o);
        } catch (Exception e) {
            throw new LobsterException("json.serialize", "JSON serialize failed: " + e.getMessage(), e);
        }
    }

    public static <T> T fromJson(String json, Class<T> type) {
        if (json == null || json.isEmpty()) return null;
        try {
            return MAPPER.readValue(json, type);
        } catch (Exception e) {
            throw new LobsterException("json.deserialize", "JSON deserialize failed: " + e.getMessage(), e);
        }
    }

    public static <T> T fromJson(String json, TypeReference<T> type) {
        if (json == null || json.isEmpty()) return null;
        try {
            return MAPPER.readValue(json, type);
        } catch (Exception e) {
            throw new LobsterException("json.deserialize", "JSON deserialize failed: " + e.getMessage(), e);
        }
    }

    public static Map<String, Object> fromJsonToMap(String json) {
        if (json == null || json.isEmpty()) return Collections.emptyMap();
        return fromJson(json, new TypeReference<Map<String, Object>>() {});
    }
}
