#include <WiFi.h>
#include <FirebaseESP32.h>

// Configuration WiFi
#define WIFI_SSID "ORANGE-DIGITAL-CENTER"
#define WIFI_PASSWORD "Welcome@2023"

// Configuration Firebase
#define FIREBASE_HOST "esp32-8a30f-default-rtdb.europe-west1.firebasedatabase.app"
#define FIREBASE_AUTH "AIzaSyAl-grjW7XlLQd03Hbs811QO8awe14_tpY"

FirebaseData fbdo;
FirebaseConfig config;
FirebaseAuth auth;

// Capteurs ultrasoniques
const int trigPin1 = 4;  // Capteur 1 (gauche)
const int echoPin1 = 2;
const int trigPin2 = 5;  // Capteur 2 (droite)
const int echoPin2 = 34;

int totalPersons = 0;
const float DISTANCE_SEUIL = 205.0; // Seuil d'activation en cm
const unsigned long TIMEOUT_PASSAGE = 1000; // Temps max entre les deux capteurs
const unsigned long DEBOUNCE_TIME = 500;    // Temps anti-rebond entre détections

// Variables pour le suivi du passage
bool capteur1Active = false;
bool capteur2Active = false;
unsigned long tempsActivationCapteur1 = 0;
unsigned long tempsActivationCapteur2 = 0;
unsigned long dernierPassage = 0; // Pour éviter les doubles détections

void setup() {
  Serial.begin(115200);

  // Connexion WiFi
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Connexion au WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nConnecté au WiFi! Adresse IP: " + WiFi.localIP().toString());

  // Initialisation Firebase
  config.host = FIREBASE_HOST;
  config.signer.tokens.legacy_token = FIREBASE_AUTH;
  Firebase.begin(&config, &auth);
  Firebase.reconnectWiFi(true);
  
  // Configuration des broches des capteurs
  pinMode(trigPin1, OUTPUT);
  pinMode(echoPin1, INPUT);
  pinMode(trigPin2, OUTPUT);
  pinMode(echoPin2, INPUT);

  Serial.println("Système prêt - Début des mesures");
  Serial.println("--------------------------------");
}

void loop() {
  float distance1 = getDistance(trigPin1, echoPin1);
  float distance2 = getDistance(trigPin2, echoPin2);

  // Affichage des distances en temps réel
  Serial.print("Capteur 1: ");
  Serial.print(distance1);
  Serial.print(" cm | Capteur 2: ");
  Serial.print(distance2);
  Serial.println(" cm");

  // Détection activation capteur 1 (avec anti-rebond)
  if (distance1 < DISTANCE_SEUIL && !capteur1Active && (millis() - dernierPassage) > DEBOUNCE_TIME) {
    capteur1Active = true;
    tempsActivationCapteur1 = millis();
    Serial.println("--> Capteur 1 activé");
  }

  // Détection activation capteur 2 (avec anti-rebond)
  if (distance2 < DISTANCE_SEUIL && !capteur2Active && (millis() - dernierPassage) > DEBOUNCE_TIME) {
    capteur2Active = true;
    tempsActivationCapteur2 = millis();
    Serial.println("--> Capteur 2 activé");
  }

  // Vérification des passages
  verifierPassage();

  // Réinitialisation si timeout
  if (capteur1Active && millis() - tempsActivationCapteur1 > TIMEOUT_PASSAGE) {
    Serial.println("Timeout capteur 1 - Reset");
    capteur1Active = false;
  }
  if (capteur2Active && millis() - tempsActivationCapteur2 > TIMEOUT_PASSAGE) {
    Serial.println("Timeout capteur 2 - Reset");
    capteur2Active = false;
  }

  delay(100); // Délai réduit pour meilleure réactivité
}

void verifierPassage() {
  // Entrée: Capteur1 puis Capteur2
  if (capteur1Active && capteur2Active) {
    if (tempsActivationCapteur1 < tempsActivationCapteur2) {
      totalPersons++;
      envoyerDonneesFirebase(totalPersons, "entree");
      Serial.println(">>>> Entrée détectée <<<<");
    } 
    // Sortie: Capteur2 puis Capteur1
    else if (tempsActivationCapteur2 < tempsActivationCapteur1) {
      if (totalPersons > 0) totalPersons--;
      envoyerDonneesFirebase(totalPersons, "sortie");
      Serial.println("<<<< Sortie détectée >>>>");
    }
    
    dernierPassage = millis();
    resetDetection();
  }
}

void resetDetection() {
  capteur1Active = false;
  capteur2Active = false;
  tempsActivationCapteur1 = 0;
  tempsActivationCapteur2 = 0;
}

void envoyerDonneesFirebase(int count, const char* type) {
  // Envoi du nombre de personnes
  if (Firebase.setInt(fbdo, "NbrPersonne/", count)) {
    Serial.print("Personnes: ");
    Serial.println(count);
  } else {
    Serial.println("Erreur NbrPersonne: " + fbdo.errorReason());
  }

  // Envoi du type de mouvement
  if (Firebase.setString(fbdo, "DernierMouvement/", type)) {
    Serial.print("Mouvement: ");
    Serial.println(type);
  } else {
    Serial.println("Erreur DernierMouvement: " + fbdo.errorReason());
  }
}

float getDistance(int trigPin, int echoPin) {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  long duration = pulseIn(echoPin, HIGH);
  return duration * 0.0343 / 2;
}
