//Client
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEClient.h>
#include <BLEServer.h>
#include <Arduino.h>

//Pin numbers
int LED = D9;

BLEClient*  pClient; //Manages the client connection
bool doconnect = false; //Create a boolean variable for when it is/isn't connected

//BLE Server name (name of the other Xiao)
#define bleServerName "Danisita_BBQ"

//Address of the peripheral device
static BLEAddress *pServerAddress;

BLEUUID serviceUUID("181A"); //Service UUID (same as the other Xiao)
BLEUUID charUUID("2A59");    //Characteristic UUID (same as the other Xiao)

uint8_t Joy; //Char variable for the received messages

//Callback function in the case of an advertising
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
  //Method for when a device is advertised:
  void onResult(BLEAdvertisedDevice advertisedDevice) {
    //Check if the name of the advertiser matches:
    if (advertisedDevice.getName() == bleServerName) { 
      //Scan can be stopped, we found what we are looking for
      advertisedDevice.getScan()->stop(); 
      //Address of advertised device is the one we need:
      pServerAddress = new BLEAddress(advertisedDevice.getAddress()); 
      Serial.println("Device found. Connecting!");
    }
  }
};


void setup() {
  pinMode(LED, OUTPUT);

  Serial.begin(115200); //Serial communication to observe prints in serial monitor

  Serial.println("Starting BLE client...");

  BLEDevice::init("Danisita_BBQ_Client"); //Create the BLE device with its name

  BLEScan* pBLEScan = BLEDevice::getScan(); //Method to scan
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());//Function for callbacks
  pBLEScan->setActiveScan(true); //Establish an active scanning (repeat it until connected)
  pBLEScan->start(30); //Begin scanning during 30 seconds

  pClient = BLEDevice::createClient(); //Create a client
  
  //Method to connect to the server with the retrieved address (line 28):
  pClient->connect(*pServerAddress); 
  Serial.println(" - Connected to server");

  //Get the reference of the searched service:
  BLERemoteService* pRemoteService = pClient->getService(serviceUUID); 
  if (pRemoteService == nullptr) { //Case in which the service UUID isn't found
    Serial.print("Failed to find our service UUID: ");
    Serial.println(serviceUUID.toString().c_str());
    return;
  }

  //Get the reference of the searched characteristic:
  BLERemoteCharacteristic* pCharacteristic = pRemoteService->getCharacteristic(charUUID); 
  if (pCharacteristic == nullptr) { //Case in which the cahracteristic isn't found
    Serial.print("Failed to find our characteristic UUID");
    return;
  }

  Serial.println(" - Found characteristics");
  
  //Notification for the first time:
  pCharacteristic->registerForNotify([](BLERemoteCharacteristic* pBLERemoteCharacteristic, uint8_t* 
  pData, size_t length, bool isNotify) {
    Serial.println("Notify received");
    Serial.print("Value: ");
    Serial.println(*pData); //pData is the message received
  });

  doconnect = true; //Flag to indicate the connection
  
}

void loop() {
  if (doconnect) {
    //Look for the service UUID and returns if the remote service exists
    BLERemoteService* pRemoteService = pClient->getService(serviceUUID); 
    //Look for the service UUID and returns if the remote characteristic exists:
    BLERemoteCharacteristic* pCharacteristic = pRemoteService->getCharacteristic(charUUID); 
    pCharacteristic->registerForNotify([](BLERemoteCharacteristic* pBLERemoteCharacteristic, uint8_t* 
    pData, size_t length, bool isNotify) { //Registers the notifications
      //Serial.println("Notify received");
      //Serial.print("Value: ");
      Joy = *pData; //Save the message received in a variable (that's easier for me to visualize it)
      //Serial.println(Joy); //Print it in the serial monitor
      
      if(Joy == 0){ //STOP
        digitalWrite(LED,LOW);
      }
      else if(Joy == 1){ //UP
        digitalWrite(LED,HIGH);
      }
      else if(Joy == 2){ //RIGHT
        digitalWrite(LED,HIGH);
      }
      else if(Joy == 3){ //DOWN
        digitalWrite(LED,HIGH);
      }
      else if(Joy == 4){ //LEFT
        digitalWrite(LED,HIGH);
      }
      else{ //STOP (just in case)
        digitalWrite(LED,LOW);
      }
      });
  }
  
  delay(1000);
  }