package cn.iocoder.foodnexus.framework.common.util.json.databind;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;


/**
 * @author : yanghao
 * create at:  2025/11/4  10:22
 * @description:
 */
public class FlexibleLocalDateTimeDeserializer extends StdDeserializer<LocalDateTime> {
    private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private static final ZoneId DEFAULT_ZONE = ZoneId.of("GMT+8");

    public FlexibleLocalDateTimeDeserializer() {
        super(LocalDateTime.class);
    }

    @Override
    public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String value = p.getValueAsString();
        if (value == null || value.trim().isEmpty()) {
            return null;
        }
        value = value.trim();

        // 1. 尝试解析时间戳（毫秒级）
        try {
            long timestamp = Long.parseLong(value);
            return Instant.ofEpochMilli(timestamp).atZone(DEFAULT_ZONE).toLocalDateTime();
        } catch (NumberFormatException e) {
            // 2. 尝试解析 ISO 8601 格式（带 Z 或时区偏移）
            try {
                ZonedDateTime zonedDateTime = ZonedDateTime.parse(value);
                return zonedDateTime.withZoneSameInstant(DEFAULT_ZONE).toLocalDateTime();
            } catch (DateTimeParseException ex) {
                // 3. 尝试解析 yyyy-MM-dd HH:mm:ss 字符串格式
                try {
                    return LocalDateTime.parse(value, DATETIME_FORMATTER);
                } catch (DateTimeParseException exc) {
                    throw new IOException(
                            "无法解析LocalDateTime：" + value +
                                    "，支持格式：时间戳（毫秒）、yyyy-MM-dd HH:mm:ss、ISO 8601（如 2025-11-04T06:00:00.000Z）",
                            exc
                    );
                }
            }
        }
    }
}
