#include <WiFi.h>
#include <HTTPClient.h>

const char* wifiSSID = "Wokwi-GUEST";
const char* wifiPassword = "";

const int ledPin = 2; // Pin para controlar el LED
const int potPin = 34; // Pin para leer el potenciómetro

String firebaseHost = "apiot-8848f-default-rtdb.firebaseio.com";
String firebaseApiKey = "zaLVDliOyg7oL1RMSQtU0m7Qqap3rX3rh4CfEbd0";
String herokuServerURL = "https://esp32-5d7f8d64c991.herokuapp.com/iot";

String firebaseLedPath = "https://" + firebaseHost + "/iot/1/valor.json?auth=" + firebaseApiKey;
String firebasePotPath = "https://" + firebaseHost + "/iot/2/valor.json?auth=" + firebaseApiKey;

unsigned long lastTime = 0;
unsigned long timerDelay = 100; // Intervalo de tiempo para consultar el estado en milisegundos (100 milisegundos)

void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);

  connectToWiFi();
  Serial.println("Actualización en tiempo real del potenciómetro.");
}

void loop() {
  if (WiFi.status() == WL_CONNECTED) {
    // Consulta el valor del potenciómetro
    int potValue = map(analogRead(potPin), 0, 4095, 0, 100);
    updateFirebase(firebasePotPath, potValue);

    // Actualiza el estado del LED basado en el potenciómetro
    int ledState = (potValue == 0) ? 0 : 1;
    digitalWrite(ledPin, ledState);
    updateFirebase(firebaseLedPath, ledState);

    // Después de actualizar en Firebase, también actualiza en Heroku
    updateHeroku(1, ledState);
    updateHeroku(2, potValue);

    Serial.println("Potenciómetro: " + String(potValue) + "% | LED: " + String(ledState == 1 ? "encendido" : "apagado"));
  } else {
    Serial.println("WiFi Desconectado");
    // Intentar reconexión si se pierde la conexión
    connectToWiFi();
  }
  delay(100); // Pequeño retardo para evitar la saturación del servidor
}

void connectToWiFi() {
  Serial.print("Conectando a WiFi");
  int attempts = 0;

  while (WiFi.status() != WL_CONNECTED && attempts < 20) {
    WiFi.begin(wifiSSID, wifiPassword);
    delay(1000);
    Serial.print(".");
    attempts++;
  }

  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("\nConectado a la red WiFi con dirección IP: " + WiFi.localIP().toString());
  } else {
    Serial.println("\nNo se pudo conectar a la red WiFi después de varios intentos.");
  }
}

void updateFirebase(String path, int value) {
  HTTPClient http;
  http.begin(path.c_str());

  // Configura el tipo de contenido para la carga útil JSON
  http.addHeader("Content-Type", "application/json");

  // Crea la carga útil JSON
  String payload = "{\"valor\":" + String(value) + "}";

  // Realiza la solicitud PUT con la carga útil JSON
  int httpResponseCode = http.PUT(payload);

  // Muestra el resultado de la solicitud HTTP
  Serial.print("HTTP Response code (Firebase): ");
  Serial.println(httpResponseCode);

  // Cierra la conexión HTTP
  http.end();
}

void updateHeroku(int deviceId, int value) {
  String herokuPath;

  // Verifica el ID del dispositivo y construye la ruta correspondiente
  if (deviceId == 1) {
    // Ruta para actualizar el valor del LED
    herokuPath = herokuServerURL + "/1/" + value;
  } else if (deviceId == 2) {
    // Ruta para actualizar el valor del potenciómetro
    herokuPath = herokuServerURL + "/2/" + value;
  } else {
    
    Serial.println("ID de dispositivo no reconocido");
    return;
  }

  HTTPClient http;
  http.begin(herokuPath.c_str());

  // Configura el tipo de contenido para la carga util JSON
  http.addHeader("Content-Type", "application/json");

  // Crea la carga util JSON
  String payload = String(value);

  // Realiza la solicitud PUT con la carga util JSON
  int httpResponseCode = http.PUT(payload);

  // Muestra el resultado de la solicitud HTTP
  Serial.print("HTTP Response code (Heroku): ");
  Serial.println(httpResponseCode);

  // Cierra la conexion HTTP
  http.end();
}