#pragma once

#include <string>
#include <functional>
#include <memory>
#include <atomic>
#include <mutex>
#include <paho_mqtt/mqtt/async_client.h>
#include "mqtt_config.hpp"

class MQTTClient : public virtual mqtt::callback
{
public:
    using ConnectCallback = std::function<void()>;
    using DisconnectCallback = std::function<void()>;
    using MessageCallback = std::function<void(const std::string &topic, const std::string &message)>;

    explicit MQTTClient(const MQTTConfig &config);
    ~MQTTClient();

    void setConnectCallback(ConnectCallback cb);
    void setDisconnectCallback(DisconnectCallback cb);
    void setMessageCallback(MessageCallback cb);

    void connect();
    void disconnect();
    void publish(const std::string &topic, const std::string &payload, int qos = -1);
    void subscribe(const std::string &topic, int qos = -1);
    void switchServer(const MQTTConfig &newConfig);

    bool isConnected() const;

private:
    void initializeClient();
    void startReconnect();

    // mqtt::callback 实现
    void connection_lost(const std::string &cause) override;
    void message_arrived(mqtt::const_message_ptr msg) override;
    void delivery_complete(mqtt::delivery_token_ptr token) override {}

    MQTTConfig config_;
    std::shared_ptr<mqtt::async_client> client_;
    std::atomic<bool> connected_;
    std::atomic<bool> reconnect_active_;
    std::mutex mutex_;

    ConnectCallback on_connect_;
    DisconnectCallback on_disconnect_;
    MessageCallback on_message_;
};
