/**********************************************************************************
 *  TITLE: Remember Last GPIO State of ESP32 after RESET using Preferences Library
 *  Related Blog : https://iotcircuithub.com/esp32-projects/
 *  by Tech StudyCell
 **********************************************************************************/

#include <Preferences.h>
Preferences pref;

const int buttonPin = 13; //BOOT button
const int buttonPin2 = 12;
const int ledPin = 2;   //D2 (inbuilt LED)   

bool ledState;         
bool buttonState;             
int lastButtonState = LOW;

unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time

void setup() { 
  Serial.begin(115200);

  //Create a namespace called "gpio-state" with read/write mode
  pref.begin("gpio-state", false);

  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);

  // read the last LED state from nvs flash memory
  ledState = pref.getBool("state", false); 
  Serial.printf("LED state before reset: %d \n", ledState);
  // set the LED to the last stored state
  digitalWrite(ledPin, ledState);
}

void loop() {
  int reading = digitalRead(buttonPin);
  int reading2 = digitalRead(buttonPin2);

  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
      if (buttonState == LOW) {
        ledState = !ledState;
      }
    }
  }
  lastButtonState = reading;
  if (digitalRead(ledPin)!= ledState) {  
    Serial.println("State changed");
    // change the LED state
    digitalWrite(ledPin, ledState);
    
    // save the LED state in flash memory
    pref.putBool("state", ledState);
    
    Serial.printf("State saved: %d \n", ledState);
  }
  if (reading2 == 0) {
     Serial.println("BYE");
    ESP.restart();
  }
}