#pragma once

#include "mqtt/async_client.h"
#include <string>
#include <iostream>

class MQTTClientWrapper
{
public:
    MQTTClientWrapper(const std::string &server_address, const std::string &client_id,
                      const std::string &username = "", const std::string &password = "")
        : client_(server_address, client_id), connOpts_()
    {
        connOpts_.set_clean_start(true);
        if (!username.empty())
        {
            connOpts_.set_user_name(username);
            connOpts_.set_password(password);
        }
    }

    bool connect()
    {
        try
        {
            mqtt::token_ptr conntok = client_.connect(connOpts_);
            conntok->wait(); // 阻塞直到连接完成
            std::cout << "MQTT connected successfully" << std::endl;
            return true;
        }
        catch (const mqtt::exception &e)
        {
            std::cerr << "MQTT connection failed: " << e.what() << std::endl;
            return false;
        }
    }

    void disconnect()
    {
        try
        {
            client_.disconnect()->wait();
            std::cout << "MQTT disconnected." << std::endl;
        }
        catch (const mqtt::exception &e)
        {
            std::cerr << "MQTT disconnect error: " << e.what() << std::endl;
        }
    }

    void publish(const std::string &topic, const std::string &payload, int qos = 1, bool retained = false)
    {
        try
        {
            auto msg = mqtt::make_message(topic, payload);
            msg->set_qos(qos);
            msg->set_retained(retained);
            client_.publish(msg);
        }
        catch (const mqtt::exception &e)
        {
            std::cerr << "MQTT publish error: " << e.what() << std::endl;
        }
    }

private:
    mqtt::async_client client_;
    mqtt::connect_options connOpts_;
};
