#include <Wire.h>
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 4);

#define menuPin 2 // Menu button pin
#define upPin 3   // Up button pin
#define downPin 4 // Down button pin
#define startPin 5 // Start/Pause/Reset button pin
#define relayPin 12 // Relay pin
#define buzzerPin 13 // Buzzer pin

unsigned long timing[6] = {1800, 2400, 3600, 4500, 0, 6000}; // Default times in seconds
unsigned long customTime = 3600; // Default custom time for V9
unsigned long startTime = 0;
unsigned long pausedTime = 0;
unsigned long pressStartTime = 0; // For detecting long press
const unsigned long longPressDuration = 2000; // 2 seconds for long press

int menuState = 0; // Current menu position
bool running = false; // Whether the timer is running
bool paused = false; // Whether the timer is paused

void setup() {
  pinMode(menuPin, INPUT_PULLUP);
  pinMode(upPin, INPUT_PULLUP);
  pinMode(downPin, INPUT_PULLUP);
  pinMode(startPin, INPUT_PULLUP);
  pinMode(relayPin, OUTPUT);
  pinMode(buzzerPin, OUTPUT);
  digitalWrite(relayPin, LOW);

  lcd.begin(16, 4);
  lcd.backlight();

  // Display startup screen
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Varuna Electric");
  lcd.setCursor(0, 1);
  lcd.print("V6 IR Checking");
  lcd.setCursor(0, 2);
  lcd.print("By-Shubham Sutar");
  lcd.setCursor(0, 3);
  lcd.print("(7410555337)");
  delay(3000); // Display for 3 seconds
  displayMainScreen();
}

void loop() {
  static unsigned long lastButtonPress = 0;
  if (millis() - lastButtonPress > 200) { // Debounce delay
    if (!digitalRead(menuPin)) {
      lastButtonPress = millis();
      handleMenuPress();
    }
    if (!digitalRead(upPin)) {
      lastButtonPress = millis();
      handleUpPress();
    }
    if (!digitalRead(downPin)) {
      lastButtonPress = millis();
      handleDownPress();
    }
    handleStartButton();
  }

  if (running && !paused) {
    handleTimer();
  }
}

void handleStartButton() {
  bool isPressed = !digitalRead(startPin);
  if (isPressed && pressStartTime == 0) {
    pressStartTime = millis();
  }
  if (!isPressed && pressStartTime > 0) {
    unsigned long pressDuration = millis() - pressStartTime;
    if (pressDuration >= longPressDuration) {
      // Reset timer logic
      lcd.clear();
      displayMainScreen();
      running = false;
      paused = false;
    } else if (running && !paused) {
      // Pause timer
      paused = true;
      pausedTime = millis() - startTime;
      lcd.setCursor(5, 2);
      lcd.print("Paused    ");
    } else if (paused) {
      // Resume timer
      paused = false;
      startTime = millis() - pausedTime;
      lcd.setCursor(5, 2);
      lcd.print("          ");
    } else {
      // Start timer
      startTime = millis();
      running = true;
      paused = false;
      displayTimerRunning();
    }
    pressStartTime = 0;
  }
}

void displayMainScreen() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Select Product");
  lcd.setCursor(0, 1);
  lcd.print("V4 to V9");
}

void handleMenuPress() {
  if (running || paused) return; // Disable menu navigation during timing
  menuState++;
  if (menuState > 6) {
    menuState = 0;
    displayMainScreen();
  } else {
    displayTimerSetting();
  }
  tone(buzzerPin, 1000, 100); // Beep sound
}

void handleUpPress() {
  if (menuState == 0 || running || paused) return; // Ignore if on main screen or timing
  adjustTimer(true);
}

void handleDownPress() {
  if (menuState == 0 || running || paused) return; // Ignore if on main screen or timing
  adjustTimer(false);
}

void adjustTimer(bool increase) {
  unsigned long increment = 60; // Increment by 1 minute
  if (menuState == 6) { // Custom timer for V9
    customTime = increase ? customTime + increment : (customTime > increment ? customTime - increment : customTime);
  } else {
    unsigned long currentSetting = timing[menuState - 1];
    timing[menuState - 1] = increase ? currentSetting + increment : (currentSetting > increment ? currentSetting - increment : currentSetting);
  }
  displayTimerSetting();
  tone(buzzerPin, 1000, 100); // Beep sound
}

void displayTimerSetting() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Set Time for V");
  lcd.print(menuState + 3);
  lcd.setCursor(0, 1);
  unsigned long timeDisplay = (menuState == 6) ? customTime : timing[menuState - 1];
  lcd.print("Time: ");
  lcd.print(timeDisplay / 60);
  lcd.print(" min");
}

void displayTimerRunning() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Running V");
  lcd.print(menuState + 3);
  updateTimerDisplay();
}

void updateTimerDisplay() {
  unsigned long remaining = (startTime + ((menuState == 6 ? customTime : timing[menuState - 1]) * 1000) - millis()) / 1000;
  lcd.setCursor(0, 1);
  lcd.print("Time left: ");
  lcd.print(remaining / 60);
  lcd.print(":");
  if (remaining % 60 < 10) lcd.print("0"); // Pad single digit seconds with zero
  lcd.print(remaining % 60);
}

void handleTimer() {
  unsigned long currentTimer = (menuState == 6 ? customTime : timing[menuState - 1]) * 1000;
  if (millis() - startTime >= currentTimer) {
    running = false;
    digitalWrite(relayPin, LOW);
    tone(buzzerPin, 1000, 500); // Beep for 0.5 seconds
    displayMainScreen();
  } else {
    updateTimerDisplay();
  }
}