package com.yupi.project.mqtt;

import com.yupi.project.config.properties.MqttLoggerProperties;
import com.yupi.project.config.properties.MqttProperties; // 主业务的 properties，获取QoS等
import com.yupi.project.service.MqttCommunicationLogService;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.UUID;

@Slf4j
@Component("mqttLoggerCallbackHandler") // 指定Bean名称
public class MqttLoggerCallbackHandler implements MqttCallbackExtended {

    private final MqttCommunicationLogService logService;
    private final MqttLoggerProperties loggerProperties;
    private final MqttProperties mainMqttProperties; // 用于获取默认QoS等
    private MqttClient mqttLoggerClient; // 通过setter注入

    public MqttLoggerCallbackHandler(MqttCommunicationLogService logService,
                                     MqttLoggerProperties loggerProperties,
                                     MqttProperties mainMqttProperties) {
        this.logService = logService;
        this.loggerProperties = loggerProperties;
        this.mainMqttProperties = mainMqttProperties;
    }

    public void setMqttClient(@Qualifier("mqttLoggerClient") MqttClient mqttLoggerClient) {
        this.mqttLoggerClient = mqttLoggerClient;
    }

    @Override
    public void connectComplete(boolean reconnect, String serverURI) {
        log.info("MQTT Logger Client connection {} to broker: {}", reconnect ? "re-established" : "established", serverURI);
        if (!loggerProperties.isEnabled() || mqttLoggerClient == null) {
            log.warn("MQTT Logger is disabled or client not initialized. Cannot subscribe to topics for logging.");
            return;
        }
        try {
            List<String> topicsToLog = loggerProperties.getTopics();
            if (topicsToLog != null && !topicsToLog.isEmpty()) {
                for (String topicFilter : topicsToLog) {
                    // 使用主配置的QoS等级进行订阅，或者在loggerProperties中单独配置
                    mqttLoggerClient.subscribe(topicFilter, mainMqttProperties.getDefaultQos());
                    log.info("MQTT Logger Client subscribed to topic: {} for logging.", topicFilter);
                }
            } else {
                log.warn("No topics configured for MQTT Logger Client to subscribe.");
            }
        } catch (Exception e) {
            log.error("Error subscribing MQTT Logger Client to topics: ", e);
        }
    }

    @Override
    public void connectionLost(Throwable cause) {
        log.error("MQTT Logger Client connection lost!", cause);
    }

    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
        if (!loggerProperties.isEnabled()) {
            return; // 如果日志功能被禁用，则不处理
        }
        // 异步记录上行消息 (UPSTREAM)
        // clientId 可以从 mqttLoggerClient.getClientId() 获取，表示是日志客户端收到的
        // messageIdStr可以尝试从 MQTTv5 属性获取，如果使用的是 MQTTv3，Paho 的 message.getId() 是内部ID，对于 broker 可能无意义
        // 对于日志记录，如果 message.getId() > 0，可以用它，否则生成一个UUID
        String messageIdStr = message.getId() > 0 ? String.valueOf(message.getId()) : UUID.randomUUID().toString();
        logService.asyncLogMessage(topic, message, "UPSTREAM", mqttLoggerClient.getClientId(), messageIdStr, null, null, null, null);
    }

    @Override
    public void deliveryComplete(IMqttDeliveryToken token) {
        // Logger client typically does not publish, so this might not be very relevant
        // unless it's used for some diagnostic publishing.
        try {
            if (token != null && token.isComplete() && token.getMessage() != null) {
                log.trace("MQTT Logger Client: Delivery complete for message ID: {}", token.getMessageId());
            }
        } catch (Exception e) {
            log.error("Error in MQTT Logger Client deliveryComplete: ", e);
        }
    }
} 