#include <WiFi.h>
#include <DHT.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// DHT Sensor setup
#define DHTPIN 15
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

// OLED setup
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET    -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// LED setup
#define LED_GREEN 12
#define LED_RED 13
#define LED_YELLOW 14

// Thresholds for temperature and humidity
float H_t = 40.0;
float L_t = 20.0;
float H_h = 80.0;
float L_h = 60.0;

String prevWeather = "";

void setup() {
  Serial.begin(115200);
  dht.begin();

  // OLED display initialization
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Halt execution if OLED setup fails
  }
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.print("Initializing...");
  display.display();

  // Initialize LED pins
  pinMode(LED_GREEN, OUTPUT);
  pinMode(LED_RED, OUTPUT);
  pinMode(LED_YELLOW, OUTPUT);

  // Turn off all LEDs initially
  digitalWrite(LED_GREEN, LOW);
  digitalWrite(LED_RED, LOW);
  digitalWrite(LED_YELLOW, LOW);
}

void blinkLED(int ledPin) {
  digitalWrite(ledPin, HIGH);
  delay(200);
  digitalWrite(ledPin, LOW);
  delay(200);
}

void controlLEDs(float temp, float hum) {
  if (temp >= L_t && temp <= H_t && hum >= L_h && hum <= H_h) {
    digitalWrite(LED_GREEN, HIGH);
    digitalWrite(LED_RED, LOW);
    digitalWrite(LED_YELLOW, LOW);
  } else {
    digitalWrite(LED_GREEN, LOW);

    if (temp < L_t) {
      digitalWrite(LED_RED, HIGH);
      digitalWrite(LED_YELLOW, LOW);
    } else if (temp > H_t) {
      blinkLED(LED_RED);
      digitalWrite(LED_YELLOW, LOW);
    }

    if (hum < L_h) {
      digitalWrite(LED_YELLOW, HIGH);
      digitalWrite(LED_RED, LOW);
    } else if (hum > H_h) {
      blinkLED(LED_YELLOW);
      digitalWrite(LED_RED, LOW);
    }
  }
}

void loop() {
  // Reading weather conditions
  float temperature = dht.readTemperature();
  float humidity = dht.readHumidity();

  if (isnan(temperature) || isnan(humidity)) {
    Serial.println("Failed to read from DHT sensor!");
    display.clearDisplay();
    display.setCursor(0, 0);
    display.print("DHT sensor error!");
    display.display();
    return;
  }

  String currentWeather = "{\"temp\": " + String(temperature) + ", \"humidity\": " + String(humidity) + "}";

  if (currentWeather != prevWeather) {
    // Display updated data on OLED
    display.clearDisplay();
    display.setCursor(0, 0);
    display.print("Temp: ");
    display.print(temperature);
    display.print(" C");
    display.setCursor(0, 16);
    display.print("Humidity: ");
    display.print(humidity);
    display.print(" %");
    display.display();

    // Control LEDs based on temperature and humidity
    controlLEDs(temperature, humidity);

    // Update previous weather data
    prevWeather = currentWeather;
  } else {
    Serial.println("No change");
  }
  delay(2000); // Delay between readings
}