#include WiFi.h>
#include esp_now.h>
#include esp_wifi.h>

// =====================
// CONFIG
// =====================
const int led1 = 6;

// MAC address of ESP32 DevKit V1
uint8_t devkitAddress[] = {0x1C, 0xC3, 0xAB, 0xB4, 0x0C, 0xAC};

// Shared message structure
typedef struct struct_message {
  char command[16];
  int value;
} struct_message;

struct_message incomingMessage;
struct_message outgoingMessage;

volatile bool triggerReceived = false;

// =====================
// CALLBACKS
// =====================
void onDataSent(const wifi_tx_info_t *info, esp_now_send_status_t status) {
  Serial.print("Send status: ");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Success" : "Fail");
}

void onDataRecv(const esp_now_recv_info_t *info, const uint8_t *incomingData, int len) {
  memcpy(&incomingMessage, incomingData, sizeof(incomingMessage));

  Serial.print("Received command: ");
  Serial.print(incomingMessage.command);
  Serial.print(" | value: ");
  Serial.println(incomingMessage.value);

  if (strcmp(incomingMessage.command, "TRIGGER") == 0) {
    triggerReceived = true;
  }
}

// =====================
// HELPER
// =====================
void blinkLedAndSendAck() {
  Serial.println("Executing LED test...");

  for (int i = 0; i < 3; i++) {
    digitalWrite(led1, HIGH);
    delay(200);
    digitalWrite(led1, LOW);
    delay(200);
  }

  strcpy(outgoingMessage.command, "ACK");
  outgoingMessage.value = 1;

  esp_err_t result = esp_now_send(devkitAddress, (uint8_t *)&outgoingMessage, sizeof(outgoingMessage));

  if (result == ESP_OK) {
    Serial.println("ACK sent");
  } else {
    Serial.print("Error sending ACK: ");
    Serial.println(result);
  }
}

// =====================
// SETUP
// =====================
void setup() {
  Serial.begin(115200);
  delay(1000);

  pinMode(led1, OUTPUT);
  digitalWrite(led1, LOW);

  WiFi.mode(WIFI_STA);
  WiFi.disconnect();

  // Force same WiFi channel on both boards
  esp_wifi_set_promiscuous(true);
  esp_wifi_set_channel(1, WIFI_SECOND_CHAN_NONE);
  esp_wifi_set_promiscuous(false);

  Serial.println("ESP32-C3-Zero - ESP-NOW Receiver/Sender");
  Serial.print("My MAC address: ");
  Serial.println(WiFi.macAddress());

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

  esp_now_register_send_cb(onDataSent);
  esp_now_register_recv_cb(onDataRecv);

  esp_now_peer_info_t peerInfo = {};
  memcpy(peerInfo.peer_addr, devkitAddress, 6);
  peerInfo.channel = 1;
  peerInfo.encrypt = false;

  if (esp_now_add_peer(&peerInfo) != ESP_OK) {
    Serial.println("Failed to add peer");
    return;
  }

  Serial.println("Peer added successfully");
  Serial.println("Waiting for TRIGGER...");
}

// =====================
// LOOP
// =====================
void loop() {
  if (triggerReceived) {
    triggerReceived = false;
    blinkLedAndSendAck();
  }
}