#include "DHTesp.h"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define SDA_PIN 21
#define SCL_PIN 22


const int DHT_PIN = 15;
const int d_buttonPin = 13;
const int tempUpButtonPin = 14;   // Button to increase high temperature
const int tempDownButtonPin = 23; // Button to decrease low temperature
const int setButtonPin = 19;      // Set button (for saving the temperature values)
const int editTempButtonPin = 18; // Edit button (to switch between edit modes)

DHTesp dhtSensor; // DHT sensor instance
int temp;
int hum;

#define BLYNK_TEMPLATE_ID "TMPL6NsbACGX0"
#define BLYNK_TEMPLATE_NAME "Temperature Humidity Monitor"
#define BLYNK_AUTH_TOKEN "cv5-VIIdK0oBnn91ZpFfpGqz-hwB7A08"

#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>

char ssid[] = "Wokwi-GUEST";
char pass[] = "";

#define RELAY1_PIN 25
#define VIRTUAL_RELAY1 V2
#define VIRTUAL_TEMP V0
#define VIRTUAL_HUM V1
#define VIRTUAL_DOOR V3

BlynkTimer timer;

// LCD display
LiquidCrystal_I2C lcd(0x27, 16, 2);  // I2C address of LCD, 16 columns, 2 rows

// Temperature limits
int hightemp = 37;  // Initial high temperature (in °C)
int lowtemp = 30;   // Initial low temperature (in °C)

int currentState = 0;  // 0: Main menu, 1: Editing high temp, 2: Editing low temp

BLYNK_WRITE(VIRTUAL_RELAY1) {
  int value = param.asInt();
  digitalWrite(RELAY1_PIN, value);
  Serial.println(value ? "Relay 1 ON (LED 1)" : "Relay 1 OFF (LED 1)");
}

unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 200; // milliseconds


void myTimerEvent() {
  TempAndHumidity data = dhtSensor.getTempAndHumidity();
  temp = data.temperature;
  hum = data.humidity;

  Serial.println("Temp: " + String(temp) + "°C");
  Serial.println("Humidity: " + String(hum) + "%");
  Serial.println("---");

  // Handle button press and mode switching with debounce
  handleButtonPress();

  // Update LCD with current state
  updateLCD();

  // Control relay based on temperature
  if (temp >= hightemp) {
    digitalWrite(RELAY1_PIN, LOW); // Turn OFF relay if temperature exceeds high temp
  } else if (temp < lowtemp) {
    digitalWrite(RELAY1_PIN, HIGH); // Turn ON relay if temperature drops below low temp
  }

  // Handle temperature adjustments in edit mode
  if (currentState == 1) {  // Editing high temperature
    if (digitalRead(tempUpButtonPin) == LOW) {
      hightemp++;  // Increase high temperature
      Serial.println("High Temp Set to: " + String(hightemp));
    }
    if (digitalRead(tempDownButtonPin) == LOW) {
      hightemp--;  // Decrease high temperature
      Serial.println("High Temp Set to: " + String(hightemp));
    }
  } else if (currentState == 2) {  // Editing low temperature
    if (digitalRead(tempUpButtonPin) == LOW) {
      lowtemp++;  // Increase low temperature
      Serial.println("Low Temp Set to: " + String(lowtemp));
    }
    if (digitalRead(tempDownButtonPin) == LOW) {
      lowtemp--;  // Decrease low temperature
      Serial.println("Low Temp Set to: " + String(lowtemp));
    }
  }
}

void handleButtonPress() {
  unsigned long currentMillis = millis();

  if (currentMillis - lastDebounceTime > debounceDelay) {
    // Check if the edit button is pressed
    if (digitalRead(editTempButtonPin) == LOW) {
      // Switch between modes
      if (currentState == 0) {
        currentState = 1;  // Start editing high temp
      } else if (currentState == 1) {
        currentState = 2;  // Start editing low temp
      } else if (currentState == 2) {
        currentState = 0;  // Go back to main menu
      }
      lastDebounceTime = currentMillis;  // Update last debounce time
    }
  }
}

void updateLCD() {
  lcd.clear();

  if (currentState == 0) {
    lcd.setCursor(0, 0);
    lcd.print("Temp: " + String(temp) + "C");
    lcd.setCursor(0, 1);
    lcd.print("Humidity: " + String(hum) + "%");
  } else if (currentState == 1) {
    lcd.setCursor(0, 0);
    lcd.print("Edit High Temp");
    lcd.setCursor(0, 1);
    lcd.print("Temp: " + String(hightemp));
  } else if (currentState == 2) {
    lcd.setCursor(0, 0);
    lcd.print("Edit Low Temp");
    lcd.setCursor(0, 1);
    lcd.print("Temp: " + String(lowtemp));
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(RELAY1_PIN, OUTPUT);
  pinMode(d_buttonPin, INPUT_PULLUP);
  pinMode(tempUpButtonPin, INPUT_PULLUP);
  pinMode(tempDownButtonPin, INPUT_PULLUP);
  pinMode(setButtonPin, INPUT_PULLUP);
  pinMode(editTempButtonPin, INPUT_PULLUP);

  digitalWrite(RELAY1_PIN, LOW);

  // Initialize DHT sensor
  dhtSensor.setup(DHT_PIN, DHTesp::DHT22);

  // Initialize LCD
  Wire.begin(SDA_PIN, SCL_PIN);
  lcd.init();
  lcd.backlight();
  lcd.print("Hello, World!");

  // Start the timer
  timer.setInterval(1000L, myTimerEvent);
}

void loop() {
  timer.run();
}
NOCOMNCVCCGNDINLED1PWRRelay Module