#include <ESP8266WiFi.h>
#include <FastLED.h>
#include <AdafruitIO.h>
#include <AdafruitIO_WiFi.h>
#include <Adafruit_MQTT.h>
#include <ArduinoHttpClient.h>

// Pin numbers are defined as GPIO
#define LED_PIN       15
#define NUM_LEDS      21
#define BUTTON_A      5
#define BUTTON_B      4
#define TRIG_PIN      13
#define ECHO_PIN      16
#define THRESHOLD     30    // Distance threshold value (cm)
#define BRIGHTNESS    125   // LED brightness (range 0-255)
#define LED_OFF_DELAY 3000  // LED turn-off delay (ms)

CRGB leds[NUM_LEDS];

bool objectDetected = false;  // Check object detection
bool firstRun = true;         // Check the first run
bool buttonPressed = false;   // Flag to check if one of the buttons has been pressed

// Adafruit IO Configuration
// visit io.adafruit.com if you need to create an account
// or if you need your Adafruit IO key
#define IO_USERNAME  "maker101io"
#define IO_KEY       "aio_cMrQ77o666kuutGgf0keXQW0AuMw"

// WIFI Configuration
#define WIFI_SSID    "MERT-KILIC"
#define WIFI_PASS    "fckgw1212mertkilic"

AdafruitIO_WiFi io(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS);

// Set up the 'command' feed
AdafruitIO_Feed *commandGood = io.feed("vote good");
AdafruitIO_Feed *commandBad = io.feed("vote bad");

void setup() {
  Serial.begin(115200);
  pinMode(BUTTON_A, INPUT_PULLUP);
  pinMode(BUTTON_B, INPUT_PULLUP);
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);

  // Connect to io.adafruit.com
  Serial.print("Connecting to Adafruit IO");
  io.connect();

  // Wait for a connection
  while(io.status() < AIO_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.println(io.statusText());

  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
  FastLED.show();
  FastLED.clear();
}

void loop() {
  if (detectObject()) {
    objectDetected = true;
    activateLEDs();
    waitForButtons();
    objectDetected = false;   // Reset object detection
    firstRun = false;         // Reset first run
    buttonPressed = false;    // Reset button pressed state
  }
}

bool detectObject() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  long duration = pulseIn(ECHO_PIN, HIGH);
  int distance = duration * 0.034 / 2;

  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");

  return distance <= THRESHOLD;
}

void activateLEDs() {
  if (!firstRun) { // Disable the LED from lighting up at first run
    fill_solid(leds, NUM_LEDS, CRGB::Purple);
    FastLED.show();
  }
}

void waitForButtons() {
  unsigned long buttonPressTime = millis();

  while (true) {
    if (digitalRead(BUTTON_A) == LOW) {
      commandGood->save(1);
      buttonAEffect();
      break;
    }
    if (digitalRead(BUTTON_B) == LOW) {
      commandBad->save(1);
      buttonBEffect();
      break;
    }

    unsigned long currentTime = millis();
    if (currentTime - buttonPressTime >= LED_OFF_DELAY) {
      break; // Exit loop if the LED_OFF_DELAY milliseconds have passed without any button press
    }

    delay(100);
  }
}

void buttonAEffect() {
  buttonPressed = true; // Set the Button A pressed flag
  fill_solid(leds, NUM_LEDS, CRGB::Green);
  FastLED.show();
  delay(LED_OFF_DELAY);
  fill_solid(leds, NUM_LEDS, CRGB::Black);
  FastLED.show();
}

void buttonBEffect() {
  buttonPressed = true; // Set the Button B pressed flag
  fill_solid(leds, NUM_LEDS, CRGB::Red);
  FastLED.show();
  delay(LED_OFF_DELAY);
  fill_solid(leds, NUM_LEDS, CRGB::Black);
  FastLED.show();
}
