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

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.JsonNode;
import com.lingniu.ingest.identity.VehicleIdentity;
import com.lingniu.ingest.identity.VehicleIdentitySource;

import java.time.Instant;

/**
 * MQTT 解析后的统一消息体：{@code Dispatcher} 收到的 RawFrame payload 就是这个。
 *
 * @param endpointName 来源 endpoint 逻辑名
 * @param profile      字段映射 profile（如 yutong / haipote）
 * @param topic        原始 topic
 * @param vin          VIN（解析自 payload 的 device / vin 字段，保留兼容旧调用）
 * @param externalVin  外部 VIN 字段
 * @param phone        外部手机号 / SIM 字段
 * @param deviceId     外部设备号 / 终端 ID / IMEI 字段
 * @param plateNo      外部车牌字段
 * @param resolvedVin  已解析的内部 VIN，供 RAW 和业务事件复用同一次身份查询
 * @param deviceTime   设备上报时刻
 * @param data         原始 JSON 树，供 Mapper 按 profile 提取字段
 */
public record MqttPayload(
        String endpointName,
        String profile,
        String topic,
        String vin,
        String externalVin,
        String phone,
        String deviceId,
        String plateNo,
        @JsonIgnore String resolvedVin,
        @JsonIgnore boolean identityResolved,
        @JsonIgnore String identitySource,
        @JsonIgnore String identityErrorMessage,
        Instant deviceTime,
        JsonNode data
) {
    public MqttPayload {
        resolvedVin = resolvedVin == null ? "" : resolvedVin.trim();
        identitySource = identitySource == null ? "" : identitySource.trim();
        identityErrorMessage = identityErrorMessage == null ? "" : identityErrorMessage.trim();
    }

    public MqttPayload(String endpointName,
                       String profile,
                       String topic,
                       String vin,
                       String externalVin,
                       String phone,
                       String deviceId,
                       String plateNo,
                       Instant deviceTime,
                       JsonNode data) {
        this(endpointName, profile, topic, vin, externalVin, phone, deviceId, plateNo,
                "", false, "", "", deviceTime, data);
    }

    public MqttPayload(String endpointName,
                       String profile,
                       String topic,
                       String vin,
                       Instant deviceTime,
                       JsonNode data) {
        this(endpointName, profile, topic, vin, "", "", vin, "", deviceTime, data);
    }

    public MqttPayload withIdentity(VehicleIdentity identity, String errorMessage) {
        VehicleIdentity safe = identity == null
                ? new VehicleIdentity("unknown", false, VehicleIdentitySource.UNKNOWN)
                : identity;
        return new MqttPayload(endpointName, profile, topic, vin, externalVin, phone, deviceId, plateNo,
                safe.vin(), safe.resolved(), safe.source().name(), errorMessage, deviceTime, data);
    }

    @JsonIgnore
    public boolean hasIdentitySnapshot() {
        return !identitySource.isBlank();
    }
}
