#include <esp_now.h>
#include <WiFi.h>
#include <Adafruit_NeoPixel.h>

// --- Configuration ---
#define LED_PIN     10
#define LED_COUNT   10
const long PAUSE_TIME = 500; // Set to 500ms (Half a second) as requested for pacing

// Structure definition (MUST MATCH THE SENDER)
typedef struct struct_message {
    char a[32]; // For status text
    int b;      // Integer (e.g., scaled reading)
    float c;    // Float (e.g., magnitude or raw float data)
    bool d;     // Boolean (Movement detected flag)
} struct_message;

struct_message myData;

// --- Object Declarations ---
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

// Variable to track how many pixels have been lit (This is our persistent counter)
int activePixelCount = 0;


//=============================================================
// FUNCTION DEFINITIONS (Helpers must be defined outside setup/loop)
//=============================================================

/**
 * @brief Handles lighting the next pixel and cycling the state when capacity is reached.
 */
void activateNextPixel() {
    // 1. Check if we need to reset (Cycle condition)
    if (activePixelCount >= LED_COUNT) {
        Serial.println("--- CYCLE COMPLETE! Resetting all pixels for next cycle. ---");
        strip.clear(); // Turn ALL lights off
        strip.show();  // Update the physical LEDs
        activePixelCount = 0; // Reset the counter to start over from Pixel 0
    }

    // 2. Light up the current pixel (This runs whether we just reset or not)
    if (activePixelCount < LED_COUNT) {
        // Increment the count *before* lighting, so it reflects the index being lit
        activePixelCount++; 
        
        Serial.print("Lighting Pixel Index: ");
        Serial.println(activePixelCount - 1);

        // --- COLOR MAPPING START HERE (Using your specified colors) ---
        uint32_t color;
        int current_index = activePixelCount - 1; // The physical index being lit (0, 1, 2...)

        if (current_index == 0) {
            color = strip.Color(255, 50, 50); // Reddish
        } else if (current_index == 1) {
            color = strip.Color(255, 255, 50); // Yellowish
        } else if (current_index == 2) {
            color = strip.Color(50, 255, 50); // Green
        } else if (current_index == 3) {
            color = strip.Color(50, 255, 255); // Cyan/Light Blue
        } else if (current_index == 4) {
            color = strip.Color(50, 50, 255); // Blue
        } else if (current_index == 5) {
            color = strip.Color(255, 50, 255); // Magenta/Purple
        } else if (current_index == 6) {
            color = strip.Color(255, 255, 100); // Light Yellow/Cream
        } else if (current_index == 7) {
            color = strip.Color(250, 100, 50); // Orange/Peach
        } else if (current_index == 8) {
            color = strip.Color(100, 200, 150); // Light Teal/Mint
        } else if (current_index == 9) {
            color = strip.Color(200, 80, 10); // Brownish Orange
        } else {
             // Fallback color just in case something goes wrong
             color = strip.Color(255, 0, 0); 
        }

        strip.setPixelColor(current_index, color);
        strip.show(); // Update the physical LEDs
    }
}


void OnDataRecv(const esp_now_recv_info_t *info, const uint8_t *incomingData, int len) {
    // 1. Copy the received data into our local structure variable
    memcpy(&myData, incomingData, sizeof(myData));
    
    Serial.println("=========================================");
    Serial.print("Packet Received from MAC: ");
    for (int i = 0; i < 6; i++) {
        Serial.printf("%02X", info->src_addr[i]);
        if (i < 5) Serial.print(":");
    }
    Serial.println();

    // Display the received data fields (for debugging)
    Serial.print("Char: ");
    Serial.println(myData.a);
    Serial.print("Int: ");
    Serial.println(myData.b);
    Serial.print("Float: ");
    Serial.println(myData.c);
    Serial.print("Bool: ");
    Serial.println(myData.d ? "TRUE" : "FALSE");


    // 2. CHECK THE MOVEMENT FLAG (The core requirement)
    if (myData.d == true) {
        Serial.println("\n*** MOVEMENT DETECTED! Starting timed sequence... ***");
        activateNextPixel(); // This starts the process by lighting Pixel 0
    } else {
        // If movement is NOT detected, we do nothing to the lights, 
        // allowing previously lit pixels to stay lit until a reset/cycle.
        Serial.println("Movement flag is FALSE. Lights remain as they are.");
    }
}


void setup() {
  // Initialize Serial Monitor (Use 115200 baud rate)
  Serial.begin(115200);

  // Setup the NeoPixels
  strip.begin();          
  strip.show();           // Turn OFF all pixels initially
  strip.setBrightness(50); // Set brightness to a reasonable level (0-255)


  // --- ESP-NOW Initialization ---
  WiFi.mode(WIFI_STA);

  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }
  
  // Register the Receive Callback Function
  esp_now_register_recv_cb(OnDataRecv);


  Serial.println("\n=========================================");
  Serial.println("Receiver Initialized and Listening for ESP-NOW Data...");
  Serial.print("Cycle: Lights will light up sequentially (0 -> 9). On the 11th trigger, all lights reset.");
}

void loop() {
    // The loop now just waits for external triggers to start the sequence.
    delay(20); 
}
