#ifndef MQTTITEM_H
#define MQTTITEM_H

#include "item.h"
#include "mqttclient.h"

class QString;

class MqttItem : public Item
{
	Q_OBJECT
Q_SIGNALS:
	void exposeLoaded();

public:
	inline static std::weak_ptr<MqttClient> client;

private:
	QString topic_;
	QString valueKey_;
	QString valueOn_ = "ON";
	QString valueOff_ = "OFF";
	int valueMin_ = 0;
	int valueMax_ = 255;
	int valueStep_ = 1;
	bool exposeLoaded_ = false;

	MqttClient::Subscription* subscription = nullptr;
	MqttClient::Subscription* devicesSubscription = nullptr;

	void hashId();
	void refreshSubscription();
	void onMessageReceived(const QMqttMessage& message);
	void onClientStateChanged(QMqttClient::ClientState state);
	void onDevicesMessageReceived(const QMqttMessage& message);
	void loadExposeFromDevice(const QJsonObject& device);

public:
	explicit MqttItem(QString name = "MqttItem",
	                  uint8_t value = 0,
	                  QObject *parent = nullptr);
	virtual ~MqttItem() override;

	void setTopic(const QString& topic);
	void setValueKey(const QString& valueKey);
	void setBaseTopic(const QString& baseTopic);
	void setValueOn(const QString& valueOn);
	void setValueOff(const QString& valueOff);
	void setValueMin(int min);
	void setValueMax(int max);
	void setValueStep(int step);
	void setValueType(item_value_type_t type);

	// Configure from Zigbee2MQTT expose info
	void setFromExpose(const QJsonObject& expose);

	// Trigger expose lookup from bridge/devices
	void triggerExposeLookup();

	QString getTopic() const;
	QString getValueKey() const;
	QString getValueOn() const;
	QString getValueOff() const;
	int getValueMin() const;
	int getValueMax() const;
	int getValueStep() const;
	bool getExposeLoaded() const;

	virtual void store(QJsonObject& json) override;
	virtual void load(const QJsonObject& json, const bool preserve = false) override;

protected:
	virtual void enactValue(uint8_t value) override;
};

#endif // MQTTITEM_H