package com.yupi.project.mqtt;

import com.yupi.project.service.impl.MqttMessageHandler;
import lombok.RequiredArgsConstructor;
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.stereotype.Component;
import com.yupi.project.config.properties.MqttProperties;

@Slf4j
@Component
@RequiredArgsConstructor
public class MqttCallbackHandler implements MqttCallbackExtended {

    private final MqttMessageHandler mqttMessageHandler;
    private final MqttProperties mqttProperties;
    private MqttClient mqttClient;

    public void setMqttClient(MqttClient mqttClient) {
        this.mqttClient = mqttClient;
    }

    @Override
    public void connectComplete(boolean reconnect, String serverURI) {
        log.info("MQTT connection {} to broker: {}", reconnect ? "re-established" : "established", serverURI);
        try {
            if (mqttClient != null && mqttClient.isConnected()) {
                String statusTopic = mqttProperties.getStatusTopicBase() + "/+";
                mqttClient.subscribe(statusTopic, mqttProperties.getDefaultQos(), mqttMessageHandler);
                log.info("Subscribed to MQTT topic: {} with MqttMessageHandler", statusTopic);
            } else {
                log.warn("MQTT client not available or not connected, cannot subscribe to topic.");
            }
        } catch (Exception e) {
            log.error("Error subscribing to MQTT topic after connection complete: ", e);
        }
    }

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

    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
        String payload = new String(message.getPayload());
        log.warn("Unexpected MQTT message arrived in MqttCallbackHandler. Topic: {}, QoS: {}, Payload:\n{}. " +
                 "This should ideally be handled by a specific MqttMessageHandler.", topic, message.getQos(), payload);
    }

    @Override
    public void deliveryComplete(IMqttDeliveryToken token) {
        // This callback is invoked when a message published by this client has been successfully delivered
        // Used for QoS 1 and 2. For QoS 0, it's called after the message has been handed to the network.
        try {
            if (token.isComplete() && token.getMessage() != null) {
                log.trace("MQTT message delivery complete. Message ID: {}, Payload: {}", token.getMessageId(), new String(token.getMessage().getPayload()));
            } else if (token.isComplete()){
                 log.trace("MQTT message delivery complete. Message ID: {}", token.getMessageId());
            }
        } catch (Exception e) {
            log.error("Error in MQTT deliveryComplete callback: ", e);
        }
    }
} 