#include "MqttHelper.h"

WiFiClient espClient;             //实例WiFiClient对象
PubSubClient myClient(espClient); //实例PubSubClient对象，espClient做参数

MQTTClient client(2048);

MqttHelper::MqttHelper(/* args */)
{
}

MqttHelper::~MqttHelper()
{
}

void callback(char *topic, byte *payload, unsigned int length)
{
    Serial.print("来自订阅的主题:"); //串口打印：来自订阅的主题:
    Serial.println(topic);           //串口打印订阅的主题
    Serial.print("信息：");          //串口打印：信息：
    for (int i = 0; i < length; i++) //使用循环打印接收到的信息
    {
        Serial.print((char)payload[i]);
    }
    Serial.println();
    Serial.println("-----------------------");
}

void MqttHelper::Init()
{
    while (WiFi.status() != WL_CONNECTED)
    { //判断wifi是否连接，请确保你所连接的wifi联通了互联网
        delay(3000);
        WiFi.begin(id, psw); //连接wifi
        Serial.println("正在连接wifi...");
    }
    Serial.println("WIFI 已连接！");

    myClient.setServer(mqttServer, mqttPort); //设置服务器地址，端口
    myClient.setCallback(callback);           //设定回调方式，当ESP32收到订阅消息时会调用此方法

    clientId = "ESP32Client-";
    clientId += String(random(0xffff), HEX); //生成随机客户端id

    //测试MQTT连接
    client.begin(mqttServer, mqttPort, espClient);

    Serial.println("正连接至MQTT服务器...");
    while (!client.connect(clientId.c_str(), mqttUser, mqttPsw))
    {
        Serial.print(".");
        delay(2000);
    }
    Serial.println("MQTT 已连接！");

    // while (!myClient.connected())
    // { //判断是否连接到服务器
    //     Serial.println("正连接至MQTT服务器...");
    //     if (myClient.connect(clientId.c_str(), mqttUser, mqttPsw))
    //     {
    //         Serial.println("MQTT 已连接！");
    //     }
    //     else
    //     {
    //         Serial.println("连接失败");
    //         Serial.println(myClient.state()); //重连函数
    //         delay(2000);
    //     }
    // }
    // myClient.subscribe("Down/ENERGY_POWER/BUSINESS/0"); //订阅名为ESP32的主题

    Serial.println("已订阅主题，等待消息...");
}

void MqttHelper::ReConnect()
{
    // myClient.unsubscribe("UP/ENERGY_POWER/BUSINESS/0");
    // myClient.disconnect();
    Serial.println("开始重连");
    while (!client.connect(clientId.c_str(), mqttUser, mqttPsw))
    {
        Serial.print(".");
        delay(2000);
    }
    Serial.println("MQTT 重连成功！");

    // while (!myClient.connected())
    // { //判断是否连接到服务器
    //     Serial.println("正连接至MQTT服务器...");
    //     if (myClient.connect(clientId.c_str(), mqttUser, mqttPsw))
    //     {
    //         Serial.println("MQTT 已连接！");
    //     }
    //     else
    //     {
    //         Serial.println("连接失败");
    //         Serial.println(myClient.state());
    //         delay(2000);
    //     }
    // }
    // myClient.subscribe("Down/ENERGY_POWER/BUSINESS/0"); //订阅名为ESP32的主题
    // Serial.println("已订阅主题，等待消息...");
}

/**
 * @brief MQTT 发布数据
 *
 * @param message 需要发布的数据
 * 这个库只能发布很短的消息信息，需要拆分消息发送
 */
void MqttHelper::publish(String message)
{
    if (!client.connected())
        ReConnect();
    bool res = client.publish(HeartbeatTopic, message.c_str());
    if (res)
        Serial.println("数据发布成功");
    else
        Serial.println("-------------------------------数-据-发-布-失-败-------------------------------");

    // message.trim();
    // message.replace(" ", "");
    // if (!myClient.connected())
    //     ReConnect();
    // int cut = 128;                       //要拆分发送的实际大小
    // int json_str_len = message.length(); //总数据长度
    // if (json_str_len > cut)
    // {
    //     //开始发送长文件参数分别为  主题，长度，是否持续
    //     myClient.beginPublish(HeartbeatTopic, json_str_len, true);
    //     int count = json_str_len / cut;
    //     for (int i = 0; i < (count - 1); i++)
    //     {
    //         size_t WriteSizeof = myClient.print(message.substring(i * cut, (i * cut + cut)));
    //         if (WriteSizeof <= 0)
    //         {
    //             myClient.disconnect();
    //             return;
    //         }
    //     }
    //     myClient.print(message.substring(cut * (count - 1)));
    //     myClient.endPublish(); //结束发送文本
    // }
    // else
    // {
    //     myClient.publish(HeartbeatTopic, message.c_str());
    // }
    // Serial.println("MQTT 消息发布");
}

void MqttHelper::Loop()
{
    // myClient.loop(); //回旋接收函数  等待服务器返回的数据

    client.loop();
}

MqttHelper _mqttHelper;
