#include <WiFi.h>
#include <PubSubClient.h>
#include <DHTesp.h>
#include <ESP32Servo.h>
#include <LiquidCrystal_I2C.h>

#define DHT_PIN 16
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PW ""
#define MQTT_BROKER "broker.mqtt-dashboard.com"
#define MQTT_PORT 1883

WiFiClient espClient;
PubSubClient client(espClient);
DHTesp dhtSensor;
Servo myServo;
LiquidCrystal_I2C LCD = LiquidCrystal_I2C(0x27, 20, 4);

int pos = 0;
int x = 0; // Режим роботи (-1 для початкового стану)

void setup() {
  Serial.begin(115200);
  dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
  myServo.attach(15);
  LCD.init();
  LCD.backlight();

  WiFi.begin(WIFI_SSID, WIFI_PW);
  LCD.setCursor(0, 0);
  LCD.print("Connecting to WIFI");

  while (WiFi.status() != WL_CONNECTED) {
    delay(250);
    Serial.print(".");
    LCD.print(".");
  }

  Serial.println("\nConnected to WiFi");
  client.setServer(MQTT_BROKER, MQTT_PORT);
  client.setCallback(callback);

  while (!client.connected()) {
    if (client.connect("espGood", "Qwerty12", "Qwerty12")) {
      client.subscribe("AUTO");
    } else {
      delay(2000);
    }
  }

  LCD.clear();
  LCD.print("Hello, ESP32!");
}

void loop() {
  TempAndHumidity data = dhtSensor.getTempAndHumidity();
  delay(1000);

  // Діагностика для перевірки режиму
  Serial.print("Current mode (x): ");
  Serial.println(x);

  if (x == 0) {
    pos = 180; // Відкрите вікно
    myServo.write(pos);
    LCD.clear();
    LCD.print("Open POS=" + String(pos));
  } else if (x == 1) {
    if (data.temperature <= 14) {
      if (data.humidity <= 40) pos = 0;
      else if (data.humidity <= 60) pos = 0;
      else pos = map(data.humidity, 60, 100, 0, 15);
    } else if (data.temperature > 14 && data.temperature <= 18) {
      if (data.humidity <= 40) pos = 0;
      else if (data.humidity <= 60) pos = map(data.humidity, 40, 60, 0, 45);
      else pos = map(data.humidity, 60, 100, 15, 90);
    } else {
      if (data.humidity <= 40) pos = map(data.humidity, 0, 40, 0, 10);
      else if (data.humidity <= 60) pos = map(data.humidity, 40, 60, 45, 90);
      else pos = map(data.humidity, 60, 100, 90, 180);
    }

    myServo.write(pos);
    LCD.clear();
    LCD.print("Auto Mode");
    LCD.setCursor(0, 1);
    LCD.print("Temp: " + String(data.temperature, 1));
    LCD.setCursor(0, 2);
    LCD.print("Humi: " + String(data.humidity, 1));
    LCD.setCursor(0, 3);
    LCD.print("POS: " + String(pos));
  } else if (x == 2) {
    pos = 0; // Закрите вікно
    myServo.write(pos);
    LCD.clear();
    LCD.print("Close POS=" + String(pos));
  } else if (x == 3) {
    LCD.clear();
    LCD.print("Manual Mode");
    LCD.setCursor(0, 1);
    LCD.print("Temp: " + String(data.temperature, 1));
    LCD.setCursor(0, 2);
    LCD.print("Humi: " + String(data.humidity, 1));
    LCD.setCursor(0, 3);
    LCD.print("POS: " + String(pos));
  }

  client.loop();
  client.publish("GM_TEMP", String(data.temperature, 1).c_str());
  client.publish("GM_HUMI", String(data.humidity, 1).c_str());
  client.publish("GM_POS", String(pos).c_str());
  client.publish("GM_Mode", String(x).c_str()); // Публікація режиму роботи
}

void callback(char* topic, byte* payload, unsigned int length) {
  String valueString = "";
  for (int i = 0; i < length; i++) {
    valueString += (char)payload[i];
  }
  x = valueString.toInt();
  Serial.print("Received mode (x): ");
  Serial.println(x);
}