#include <FastLED.h>

#define LED_PIN 6
#define NUM_LEDS 10
#define TOUCH_PIN 2
#define IR_PIN 3
#define VIB_PIN 9

CRGB leds[NUM_LEDS];

bool systemON = false;
bool personDetected = false;
bool alertMode = false;

unsigned long touchStart = 0;
bool touchPressed = false;

unsigned long ledTimer = 0;
int currentLED = NUM_LEDS - 1;

unsigned long fadeTimer = 0;
int fadeValue = 0;
bool fadeUp = true;

#define STEP_TIME 6000   // 6 seconds per LED (~60 sec total)


// =========================
// SETUP
// =========================

void setup() {

  pinMode(TOUCH_PIN, INPUT);
  pinMode(IR_PIN, INPUT);
  pinMode(VIB_PIN, OUTPUT);

  digitalWrite(VIB_PIN, LOW);

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


// =========================
// LOOP
// =========================

void loop() {

  handleTouchPower();

  if (!systemON) {
    FastLED.clear();
    FastLED.show();
    digitalWrite(VIB_PIN, LOW);
    return;
  }

  bool irState = digitalRead(IR_PIN);

  // Assuming obstacle detected = LOW (change if needed)
  bool sitting = (irState == LOW);

  if (sitting && !personDetected) {
    personDetected = true;
    startSequence();
  }

  if (!sitting && personDetected) {
    resetSystem();
  }

  if (personDetected && !alertMode) {
    runCountdown();
  }

  if (alertMode) {
    alertEffect();
  }
}


// =========================
// TOUCH LONG PRESS POWER
// =========================

void handleTouchPower() {

  bool touch = digitalRead(TOUCH_PIN);

  if (touch && !touchPressed) {
    touchPressed = true;
    touchStart = millis();
  }

  if (!touch && touchPressed) {
    touchPressed = false;
  }

  if (touchPressed && millis() - touchStart > 2000) {

    systemON = !systemON;

    touchPressed = false;
    delay(500);
  }
}


// =========================
// START SEQUENCE
// =========================

void startSequence() {

  // Fancy green blink intro (3 times)
  for (int i = 0; i < 3; i++) {

    fill_solid(leds, NUM_LEDS, CRGB::Green);
    FastLED.show();
    delay(200);

    FastLED.clear();
    FastLED.show();
    delay(200);
  }

  fill_solid(leds, NUM_LEDS, CRGB::Green);
  FastLED.show();

  currentLED = NUM_LEDS - 1;
  ledTimer = millis();
}


// =========================
// COUNTDOWN EFFECT
// =========================

void runCountdown() {

  fancyFade();

  if (millis() - ledTimer >= STEP_TIME) {

    leds[currentLED] = CRGB::Red;
    FastLED.show();

    currentLED--;

    ledTimer = millis();

    if (currentLED < 0) {

      alertMode = true;
    }
  }
}


// =========================
// FANCY FADE (GREEN BREATHING)
// =========================

void fancyFade() {

  if (millis() - fadeTimer > 30) {

    fadeTimer = millis();

    if (fadeUp) fadeValue += 5;
    else fadeValue -= 5;

    if (fadeValue >= 255) fadeUp = false;
    if (fadeValue <= 80) fadeUp = true;

    for (int i = 0; i <= currentLED; i++) {
      leds[i] = CRGB(0, fadeValue, 0);
    }

    FastLED.show();
  }
}


// =========================
// ALERT MODE
// =========================

void alertEffect() {

  static bool blinkState = false;
  static unsigned long blinkTimer = 0;

  if (millis() - blinkTimer > 300) {

    blinkTimer = millis();
    blinkState = !blinkState;

    if (blinkState)
      fill_solid(leds, NUM_LEDS, CRGB::Red);
    else
      FastLED.clear();

    FastLED.show();
  }

  digitalWrite(VIB_PIN, HIGH);
}


// =========================
// RESET WHEN PERSON LEAVES
// =========================

void resetSystem() {

  personDetected = false;
  alertMode = false;
  currentLED = NUM_LEDS - 1;

  digitalWrite(VIB_PIN, LOW);

  fill_solid(leds, NUM_LEDS, CRGB::Black);
  FastLED.show();
}
