#include <BLEDevice.h>
#include <esp_mac.h>

// Pin Configuration
#define LED_PIN 1      // LED Pin
#define BZ_PIN 20      // Buzzer Pin

#define SERVICE_UUID      "44697e95-ce46-4fac-bdf4-4bee74427b06" // Service UUID
#define CHAR_CTRL_UUID    "9a155b2c-115a-4b3d-b36c-2dcc9a3143a9" //Characteristic UUID

BLECharacteristic *pCharCtrl; 
char myDeviceName[20]; // Array to store the BLE device name

// Callback executed when data is written via BLE
class CharCallbacks : public BLECharacteristicCallbacks {
  void onWrite(BLECharacteristic *pChar) override {
    String value = pChar->getValue(); // Get the string sent from a smartphone or other BLE device
    value.toLowerCase();  // Convert to lowercase for case-insensitive comparison

    // Display the received command on the Serial Monitor
    Serial.print("Received: ");
    Serial.println(value);

    // LED ON
    if (value == "ledon") {
      digitalWrite(LED_PIN, HIGH);
      // Notify the execution result
      pChar->setValue("LED_ON_OK");
      pChar->notify();
    }
    // LED OFF
    else if (value == "ledoff") {
      digitalWrite(LED_PIN, LOW);
      pChar->setValue("LED_OFF_OK");
      pChar->notify();
    }
    // Sound the buzzer for 1 second
    else if (value == "bz") {
      pChar->setValue("BUZZER_RINGING");
      pChar->notify();
      tone(BZ_PIN, 2000, 1000); // Sound at 2000 Hz for 1000 ms
    }
    else {
      pChar->setValue("UNKNOWN_CMD");
      pChar->notify();
    }
  }
};

// Initialization
void setup() {
  Serial.begin(115200); // Initialize serial communication
  // Configure the LED and buzzer pins as outputs
  pinMode(LED_PIN, OUTPUT);
  pinMode(BZ_PIN, OUTPUT);
  // Generate the device name from the MAC address
  uint8_t mac[6];
  esp_read_mac(mac, ESP_MAC_WIFI_STA);

  snprintf(myDeviceName,
           sizeof(myDeviceName),
           "ESP32C6_%02X%02X",
           mac[4], mac[5]);

  // Initialize BLE
  BLEDevice::init(myDeviceName);

  // Display the device name on the Serial Monitor
  Serial.print("Device Name : ");
  Serial.println(myDeviceName);

  BLEServer *pServer = BLEDevice::createServer(); // Create the BLE server
  BLEService *pService = pServer->createService(SERVICE_UUID); // Create the BLE service

 // Create the characteristic for LED and buzzer control
  pCharCtrl = pService->createCharacteristic(
      CHAR_CTRL_UUID,
      BLECharacteristic::PROPERTY_READ |
      BLECharacteristic::PROPERTY_WRITE |
      BLECharacteristic::PROPERTY_NOTIFY);

  pCharCtrl->setCallbacks(new CharCallbacks()); // Register the callback

  pCharCtrl->setValue("READY"); // Set the initial value
  pService->start(); // Start the BLE service

  // Start the BLE Advertising
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->setScanResponse(true);
  pAdvertising->start();

  Serial.println("BLE Advertising Started");
}

void loop() {
}