package com.usky.cdi.service.impl;

import com.alibaba.fastjson.JSON;
import com.usky.cdi.service.mqtt.MqttConnectionTool;
import com.usky.cdi.service.util.SnowflakeIdGenerator;
import com.usky.cdi.service.vo.alarm.AlarmMessageVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

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

/**
 * 告警类数据传输服务：向市适配平台通过 MQTT 上报告警数据。
 *
 * @author han
 * @date 2025/12/08
 */
@Slf4j
@Service
public class AlarmDataTransferService {

    private static final String MQTT_USERNAME = "3101100021";
    private static final String MQTT_PASSWORD = "SIixzph1";
    private static final String ALARM_TOPIC = "alarm/message";
    private static final DateTimeFormatter PUBLISH_TIME_FORMAT =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");

    private final MqttConnectionTool mqttConnectionTool;
    private final SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(3L, 3L);

    public AlarmDataTransferService(MqttConnectionTool mqttConnectionTool) {
        this.mqttConnectionTool = mqttConnectionTool;
    }

    private String getCurrentTime() {
        return LocalDateTime.now().format(PUBLISH_TIME_FORMAT);
    }

    private long generateDataPacketId() {
        return idGenerator.nextPacketId();
    }

    /**
     * 上报告警消息至 MQTT（topic: alarm/message）。
     *
     * @return 是否已成功投递到底层网关（不代表敌方平台一定消费成功）
     */
    public boolean publishAlarm(AlarmMessageVO<?> vo) {
        try {
            fillDefaults(vo);
            String json = JSON.toJSONString(vo);
            log.info("告警 MQTT 载荷: {}", json);
            MqttConnectionTool.MqttGateway gateway =
                    mqttConnectionTool.connectOrRefresh(MQTT_USERNAME, MQTT_PASSWORD);
            gateway.sendToMqtt(ALARM_TOPIC, json);
            return true;
        } catch (Exception e) {
            log.error("发送告警信息失败, alarmID: {}, engineeringID: {}",
                    vo != null ? vo.getAlarmID() : null,
                    vo != null ? vo.getEngineeringID() : null,
                    e);
            return false;
        }
    }

    private void fillDefaults(AlarmMessageVO<?> vo) {
        if (vo.getDataPacketID() == null) {
            vo.setDataPacketID(generateDataPacketId());
        }
        if (vo.getPublishTime() == null) {
            vo.setPublishTime(getCurrentTime());
        }
    }
}
