#include <WiFi.h>
#include <WiFiManager.h>
#include <Firebase_ESP_Client.h>
#include "DHT.h"

// ===== FIREBASE =====
#define API_KEY "AIzaSyCiOW-xdrQRerccECUA3R8Ynwgp4POPoNg"
#define DATABASE_URL "https://smartgh-2cc3c-default-rtdb.firebaseio.com/"
#define USER_EMAIL "test@gmail.com"
#define USER_PASSWORD "123456"

FirebaseData fbdo;
FirebaseAuth auth;
FirebaseConfig config;

// ===== RELAY PIN =====
int RELAY_WATER = 19;
int RELAY_FERTILIZER = 18;
int RELAY_COOLER = 25;

// ===== SENSOR PIN =====
#define DHTPIN 5
#define DHTTYPE DHT22
#define SOIL_PIN 34

DHT dht(DHTPIN, DHTTYPE);

// ===== TIMER SENSOR =====
unsigned long lastSensorTime = 0;
const unsigned long sensorInterval = 5000; // 5 detik

// Min-Max scaling limits
const int soilMinRaw = 876; // Minimum raw sensor value (wet soil)
const int soilMaxRaw = 2554; // Maximum raw sensor value (dry soil)
const float soilMinScaled = 0.0; // Minimum scaled value
const float soilMaxScaled = 100.0; // Maximum scaled value

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

  pinMode(RELAY_WATER, OUTPUT);
  pinMode(RELAY_FERTILIZER, OUTPUT);
  pinMode(RELAY_COOLER, OUTPUT);
  pinMode(SOIL_PIN, INPUT);

  digitalWrite(RELAY_WATER, HIGH);
  digitalWrite(RELAY_FERTILIZER, HIGH);
  digitalWrite(RELAY_COOLER, LOW);

  dht.begin();

  // WiFi Manager
  WiFiManager wm;
  if (!wm.autoConnect("SmartGH-Setup")) {
    Serial.println("Gagal connect, restart...");
    delay(3000);
    ESP.restart();
  }
  Serial.println("WiFi Connected.");

  // Firebase
  config.api_key = API_KEY;
  config.database_url = DATABASE_URL;
  auth.user.email = USER_EMAIL;
  auth.user.password = USER_PASSWORD;
  Firebase.begin(&config, &auth);
  Firebase.reconnectWiFi(true);
}

void loop() {
  if (Firebase.ready()) {
    // === Manual Control ===
    if (Firebase.RTDB.getBool(&fbdo, "/status/devices/water")) {
      digitalWrite(RELAY_WATER, fbdo.boolData() ? LOW : HIGH);
    }

    if (Firebase.RTDB.getBool(&fbdo, "/status/devices/fertilizer")) {
      digitalWrite(RELAY_FERTILIZER, fbdo.boolData() ? LOW : HIGH);
    }

    // === Sensor Update ===
    if (millis() - lastSensorTime > sensorInterval) {
      lastSensorTime = millis();

      float temp = dht.readTemperature();
      float hum = dht.readHumidity();
      int soilRaw = analogRead(SOIL_PIN);
      
      // Min-Max Scaling untuk Kelembapan Tanah 
      float soilPercent = (float)(soilMaxRaw - soilRaw) / (soilMaxRaw - soilMinRaw) * (soilMaxScaled - soilMinScaled) + soilMinScaled;
      soilPercent = constrain(soilPercent, 0, 100); // Membatasi agar nilai tidak melebihi 100%


      Serial.println("----- SENSOR -----");
      Serial.printf("Temp: %.1f °C\n", temp);
      Serial.printf("Hum: %.1f %%\n", hum);
      Serial.printf("Soil Raw: %d → Soil Moisture: %.1f %%\n", soilRaw, soilPercent);

      // Simpan ke Firebase
      Firebase.RTDB.setFloat(&fbdo, "/sensor/data/temperature", temp);
      Firebase.RTDB.setFloat(&fbdo, "/sensor/data/humidity", hum);
      Firebase.RTDB.setFloat(&fbdo, "/sensor/data/soilMoisture", soilPercent);

      // === Pendingin Otomatis / Manual ===
      bool manualMode = true;
      if (Firebase.RTDB.getBool(&fbdo, "/status/mode_manual/cooler")) {
        manualMode = fbdo.boolData();
      }

      if (manualMode) {
        if (Firebase.RTDB.getBool(&fbdo, "/status/devices/cooler")) {
          digitalWrite(RELAY_COOLER, fbdo.boolData() ? HIGH : LOW);
        }
        Serial.println("Cooler mode: MANUAL");
      } else {
        if (temp > 34.0) {
          digitalWrite(RELAY_COOLER, HIGH);
          Firebase.RTDB.setBool(&fbdo, "/status/devices/cooler", true);
          Serial.println("Cooler AUTO ON (Temp > 34)");
        } else {
          digitalWrite(RELAY_COOLER, LOW);
          Firebase.RTDB.setBool(&fbdo, "/status/devices/cooler", false);
          Serial.println("Cooler AUTO OFF (Temp normal)");
        }
        Serial.println("Cooler mode: AUTO");
      }

      Serial.println("--------------------\n");
    }
  }

  delay(500);
}