#include <WiFi.h>       // Required for ESP-NOW communication
#include <esp_now.h>    // ESP-NOW library for peer-to-peer communication
#include <Ultrasonic.h> // Library to interface with the HC-SR04 sensor

#define TRIGGER_PIN 12
#define ECHO_PIN 14

// leader person code = 10808180 --> 80
// define Deep Sleep time based on leader's person code (X = 35 seconds)
// X=80%50+5
#define SLEEP_TIME 35 * 1000000  // convert seconds to microseconds

// create an Ultrasonic sensor object
Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);

// MAC address of the ESP32 sink node (must be manually set)
uint8_t broadcastAddress[] = {0x8C, 0xAA, 0xB5, 0x84, 0xFB, 0x90};

// Structure to hold parking status message
typedef struct custom_string {
  char status[10]; // Will store "FREE" or "OCCUPIED"
} custom_string;

custom_string message;  // Create an instance of the struct

void setup() {
  Serial.begin(115200); // initialize Serial Monitor
  delay(100); // small delay for serial stability

  unsigned long starting_time = millis();

  // Set ESP32 to Station mode (required for ESP-NOW)
  WiFi.mode(WIFI_STA);
  Serial.println("ESP32 in STA mode");

  // Initialize ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  // define sink node
  esp_now_peer_info_t peerInfo = {};
  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
  peerInfo.channel = 0;
  peerInfo.encrypt = false;

  // Add the peer to the ESP-NOW network
  if (esp_now_add_peer(&peerInfo) != ESP_OK) {
    Serial.println("Failed to add peer");
    return;
  }

  // Configure ESP32 to wake up after SLEEP_TIME seconds
  esp_sleep_enable_timer_wakeup(SLEEP_TIME);

  delay(50); // allow sensor to stabilize after waking up

  // Measure distance using the HC-SR04 ultrasonic sensor
  long distance = ultrasonic.read();
  Serial.print("Measured Distance: ");
  Serial.print(distance);
  Serial.println(" cm");

  // Determine parking status based on measured distance
  if (distance <= 50) {
    strcpy(message.status, "OCCUPIED"); // If distance ≤ 50 cm, parking is occupied
  } else {
    strcpy(message.status, "FREE"); // If distance > 50 cm, parking is free
  }

  // Send data to the ESP32 sink node via ESP-NOW
  esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &message, sizeof(message));

  // Check if the message was sent successfully
  if (result == ESP_OK) {
    Serial.println("Message sent successfully");
  } else {
    Serial.println("Error sending message");
  }

  // Short delay to ensure ESP-NOW message is transmitted before sleep
  delay(100);
  
  unsigned long finish_time = millis();
  unsigned long cycle_time = finish_time - starting_time;
  Serial.print("Cycle time: ");
  Serial.print(cycle_time);
  Serial.println(" ms");

  Serial.println("Going to sleep now...");
  esp_deep_sleep_start(); // Enter Deep Sleep mode
}

void loop() {
  // Not needed
}