// mqtt_controller.cpp
#include "mqtt_controller.hpp"
#include <iostream>

// 构造函数：初始化客户端和回调处理器
MqttController::MqttController(const std::string& broker_address, const std::string& client_id)
    : client_(new mqtt::async_client(broker_address, client_id)),
      callback_handler_(*this),
      is_connected_(false)
{
    // 将回调处理器与客户端关联起来
    client_->set_callback(callback_handler_);
}

// 析构函数：确保断开连接
MqttController::~MqttController() {
    disconnect();
}

// 连接到代理
bool MqttController::connect(const std::string& username, const std::string& password) {
    if (isConnected()) {
        return true;
    }
    
    mqtt::connect_options conn_opts;
    conn_opts.set_keep_alive_interval(30);
    conn_opts.set_clean_session(true);
    if (!username.empty()) {
        conn_opts.set_user_name(username);
        conn_opts.set_password(password);
    }

    try {
        std::cout << "正在连接到 MQTT 代理..." << std::endl;
        // connect是异步的，它会立即返回。连接过程在后台进行。
        client_->connect(conn_opts);
    } catch (const mqtt::exception& exc) {
        std::cerr << "错误：连接时发生异常 - " << exc.what() << std::endl;
        return false;
    }
    return true;
}

// 断开连接
void MqttController::disconnect() {
    if (isConnected() || client_->is_connected()) {
        try {
            std::cout << "正在断开与 MQTT 代理的连接..." << std::endl;
            is_connected_ = false;
            // disconnect是异步的，但我们通常希望等待它完成
            client_->disconnect()->wait();
            std::cout << "已断开连接。" << std::endl;
        } catch (const mqtt::exception& exc) {
            std::cerr << "错误：断开连接时发生异常 - " << exc.what() << std::endl;
        }
    }
}

bool MqttController::isConnected() const {
    return is_connected_;
}

// 订阅主题，并为这个主题的后续消息设置回调
void MqttController::subscribe(const std::string& topic, MessageCallback callback) {
    if (!isConnected()) {
        std::cerr << "错误：未连接，无法订阅主题。" << std::endl;
        return;
    }
    
    std::cout << "正在订阅主题: " << topic << std::endl;
    message_callback_ = callback; // 保存回调函数
    client_->subscribe(topic, 1); // QoS 等级为 1
}

// 发布消息
void MqttController::publish(const std::string& topic, const std::string& payload, int qos, bool retained) {
    if (!isConnected()) {
        std::cerr << "错误：未连接，无法发布消息。" << std::endl;
        return;
    }
    
    try {
        auto msg = mqtt::make_message(topic, payload);
        msg->set_qos(qos);
        msg->set_retained(retained);
        client_->publish(msg);
    } catch (const mqtt::exception& exc) {
        std::cerr << "错误：发布消息时发生异常 - " << exc.what() << std::endl;
    }
}

// --- 内部回调处理类的实现 ---

// 连接成功时，由Paho库的后台线程调用
void MqttController::CallbackHandler::connected(const std::string& cause) {
    std::cout << "连接成功！" << std::endl;
    controller_.is_connected_ = true;
}

// 连接丢失时，由Paho库的后台线程调用
void MqttController::CallbackHandler::connection_lost(const std::string& cause) {
    std::cerr << "错误：连接已丢失。原因: " << cause << std::endl;
    controller_.is_connected_ = false;
}

// 收到消息时，由Paho库的后台线程调用
void MqttController::CallbackHandler::message_arrived(mqtt::const_message_ptr msg) {
    // 检查用户是否设置了回调函数
    if (controller_.message_callback_) {
        // 调用用户设置的C++回调函数，将消息传递出去
        controller_.message_callback_(msg->get_topic(), msg->to_string());
    }
}