package com.yupi.project.mqtt;

import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class MqttConnectionManager implements ApplicationListener<ContextRefreshedEvent>, DisposableBean {

    private final MqttClient mqttClient;
    private final MqttConnectOptions mqttConnectOptions;
    // private final MqttProperties mqttProperties; // Injected if needed for logging brokerUrl, or get from mqttClient.getServerURI()

    @Autowired
    public MqttConnectionManager(@Qualifier("mqttClientBean") MqttClient mqttClient, 
                                 MqttConnectOptions mqttConnectOptions) {
        this.mqttClient = mqttClient;
        this.mqttConnectOptions = mqttConnectOptions;
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        // Ensure this logic runs only once, for the root application context
        if (event.getApplicationContext().getParent() == null) {
            connectToMqtt();
        }
    }

    private void connectToMqtt() {
        try {
            if (mqttClient != null && !mqttClient.isConnected()) {
                log.info("Attempting to connect to MQTT broker: {} with client ID: {}", mqttClient.getServerURI(), mqttClient.getClientId());
                mqttClient.connect(mqttConnectOptions);
                // Subscription logic is handled by MqttCallbackHandler.connectComplete
                // which is triggered by the Paho client library upon successful connection.
            } else if (mqttClient == null) {
                log.error("MqttClient bean is null, cannot connect.");
            }
        } catch (MqttException e) {
            log.error("Error connecting to MQTT broker: ", e);
            // Consider retry logic or specific actions based on requirements
        }
    }

    @Override
    public void destroy() throws Exception {
        disconnectFromMqtt();
    }

    private void disconnectFromMqtt() {
        try {
            if (mqttClient != null && mqttClient.isConnected()) {
                log.info("Disconnecting from MQTT broker: {}", mqttClient.getServerURI());
                mqttClient.disconnect();
                log.info("Successfully disconnected from MQTT broker.");
            }
        } catch (MqttException e) {
            log.error("Error disconnecting from MQTT broker: ", e);
        } finally {
            try {
                if (mqttClient != null) { // No need to check isOpen(), close() handles its state.
                    log.info("Closing MQTT client for client ID: {}", mqttClient.getClientId());
                    mqttClient.close();
                    log.info("MQTT client closed successfully for client ID: {}", mqttClient.getClientId());
                }
            } catch (MqttException e) {
                // Log if close() itself throws an exception, though it's less common if called after disconnect or on an unopen client.
                log.error("Error closing MQTT client: ", e);
            }
        }
    }
} 