#include <DHTesp.h>
#include <WiFi.h>
#define THINGSBOARD_ENABLE_DEBUG 1
#include <ThingsBoard.h>
#include <Arduino_MQTT_Client.h>

// Virmware
#define CURRENT_VIRMWARE_TITLE   "TEST"
#define CURRENT_VIRMWARE_VERSION "1.0.0"

// Pins
#define DHT_PIN 15
#define WATER_SENSOR_PIN A0

// WiFi credentials
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""

// ThingsBoard
#define TB_SERVER "thingsboard.cloud"
#define TB_DEVICE_TOKEN "sz298cjwpcy4eipkylw9"

constexpr uint16_t MAX_MESSAGE_SIZE = 128U;

DHTesp dhtSensor;

WiFiClient espClient;
Arduino_MQTT_Client mqttClient(espClient);
ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE);

void setup() {
  // Initialize serial for debugging
  Serial.begin(9600);
  dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
  connectToWifi();
  connectToTB();
}

void connectToWifi() {
  Serial.println();
  Serial.println("Connecting to " + String(WIFI_SSID));

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  unsigned long startAttemptTime = millis();

  // Wait for connection with a timeout
  while (WiFi.status() != WL_CONNECTED && millis() - startAttemptTime < 10000) {
    delay(500);
    Serial.print(".");
  }

  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("");
    Serial.println("WiFi connected");
  } else {
    Serial.println("");
    Serial.println("Failed to connect to WiFi");
  }
}

void reconnectToWifi() {
  if (WiFi.status() != WL_CONNECTED) {
    connectToWifi();
  }
}

void connectToTB() {
  // Loop until we're reconnected
  while (!tb.connected()) {
    Serial.print("Connecting to ThingsBoard node ...");
    // Attempt to connect
    if (tb.connect(TB_SERVER, TB_DEVICE_TOKEN)) {
      Serial.println("[DONE]");
    } else {
      Serial.print("[FAILED]");
      Serial.println(" : retrying in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void sendSensorData(float humidity, float temperature, int waterLevel) {
  String payload = "#" + String(humidity, 2) + "," + String(temperature, 2) + "," + waterLevel;
  tb.sendTelemetryData("weatherTelemetry", payload.c_str());

  // String jsonData = "{\"humidity\":\"" + String(humidity, 2) + "\", \"temperature\":" + String(temperature, 2) + "}";
  // tb.sendTelemetryJson(jsonData.c_str());
  Serial.println("Data sent to ThingsBoard successfully: "); // + payload);
  Serial.println("---");
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) {
    reconnectToWifi();
  }

  if (!tb.connected()) {
    connectToTB();
  }

  // Collecting sensor data
  Serial.println("Collecting sensor data.");
  TempAndHumidity dhtSensorData = dhtSensor.getTempAndHumidity();
  float humidity = dhtSensorData.humidity;
  float temperature = dhtSensorData.temperature;

  Serial.println("Humidity: " + String(humidity) + "%");
  Serial.println("Temperature: " + String(temperature) + "°C");

  // Sending sensor data
  sendSensorData(humidity, temperature, 0);

  delay(5000);

  tb.loop();
}
$abcdeabcde151015202530fghijfghij