package com.lingniu.ingest.inbound.mqtt.parser;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lingniu.ingest.api.spi.DecodeException;
import com.lingniu.ingest.inbound.mqtt.model.MqttPayload;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;

/**
 * 宇通 MQTT JSON 消息基础解析器（对标旧 {@code VehicleDataReceptionVO} + {@code ReceptionDataVO}）。
 *
 * <p>约定宇通 MQTT 的 payload JSON 形如：
 * <pre>{@code
 * {
 *   "id": "xxx",
 *   "device": "LTEST000000000001",   // VIN
 *   "code": "C001",
 *   "time": "20260413100000",        // yyyyMMddHHmmss
 *   "data": { "METER_SPEED": 52, "LATITUDE": 39916527, ... }
 * }
 * }</pre>
 *
 * <p>其它厂商只需新增 {@code MqttProfile} 实现，公共 MQTT endpoint 生命周期不需要修改。
 */
public final class MqttPayloadParser {

    private static final DateTimeFormatter TIME_FMT = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
    private static final ZoneId ZONE = ZoneId.of("Asia/Shanghai");

    private final ObjectMapper mapper;

    public MqttPayloadParser(ObjectMapper mapper) {
        this.mapper = mapper;
    }

    public MqttPayload parse(String endpointName, String profile, String topic, byte[] bytes) {
        try {
            JsonNode root = mapper.readTree(bytes);
            String externalVin = text(root, "vin", "VIN");
            String deviceId = text(root, "device", "deviceId", "terminalId", "imei", "IMEI");
            String phone = text(root, "sim", "phone", "mobile");
            String plateNo = text(root, "plateNo", "carNo", "plate");
            String vin = !externalVin.isBlank() ? externalVin : deviceId;
            Instant deviceTime = parseTime(text(root, "time"));
            JsonNode data = root.has("data") ? root.get("data") : root;
            return new MqttPayload(endpointName, profile, topic,
                    vin, externalVin, phone, deviceId, plateNo, deviceTime, data);
        } catch (Exception e) {
            throw new DecodeException("mqtt payload parse failed: " + e.getMessage(), e);
        }
    }

    private static String text(JsonNode root, String... keys) {
        for (String k : keys) {
            JsonNode n = root.get(k);
            if (n != null && !n.isNull()) return n.asText();
        }
        return "";
    }

    private static Instant parseTime(String raw) {
        if (raw == null || raw.isEmpty()) return Instant.now();
        try {
            return LocalDateTime.parse(raw, TIME_FMT).atZone(ZONE).toInstant();
        } catch (Exception e) {
            return Instant.now();
        }
    }
}
