// Pomodoro Timer - Arduino Code
// Hardware Setup:
// - Button connected to pin 2 (with pull-up resistor)
// - LED 1 (Pomodoro 1) connected to pin 3
// - LED 2 (Pomodoro 2) connected to pin 4
// - LED 3 (Pomodoro 3) connected to pin 5
// - LED 4 (Pomodoro 4) connected to pin 6
// - LED 5 (Green - Long Break) connected to pin 7

// Pin definitions
const int BUTTON_PIN = 2;
const int LED_PINS[5] = {3, 4, 5, 6, 7}; // LEDs 1-4 for pomodoros, LED 5 (green) for long break

// Timing constants (in milliseconds)
const unsigned long POMODORO_DURATION = 25UL * 60UL * 1000UL;  // 25 minutes
const unsigned long SHORT_BREAK_DURATION = 5UL * 60UL * 1000UL; // 5 minutes
const unsigned long LONG_BREAK_DURATION = 30UL * 60UL * 1000UL; // 30 minutes

// State machine states
enum State {
  IDLE,
  POMODORO_1,
  BREAK_1,
  POMODORO_2,
  BREAK_2,
  POMODORO_3,
  BREAK_3,
  POMODORO_4,
  LONG_BREAK
};

// Global variables
State currentState = IDLE;
unsigned long stateStartTime = 0;
bool lastButtonState = HIGH;
bool buttonPressed = false;

void setup() {
  // Initialize button pin with internal pull-up
  pinMode(BUTTON_PIN, INPUT_PULLUP);

  // Initialize LED pins as outputs
  for (int i = 0; i < 5; i++) {
    pinMode(LED_PINS[i], OUTPUT);
    digitalWrite(LED_PINS[i], LOW);
  }

  // Optional: Initialize serial for debugging
  Serial.begin(9600);
  Serial.println("Pomodoro Timer Ready");
}

void loop() {
  // Check for button press
  checkButton();

  // Update state machine
  updateStateMachine();

  // Update LED display
  updateLEDs();
}

void checkButton() {
  bool currentButtonState = digitalRead(BUTTON_PIN);

  // Detect button press (HIGH to LOW transition with pull-up)
  if (lastButtonState == HIGH && currentButtonState == LOW) {
    delay(50); // Debounce
    currentButtonState = digitalRead(BUTTON_PIN);

    if (currentButtonState == LOW) {
      buttonPressed = true;
      Serial.println("Button pressed");
    }
  }

  lastButtonState = currentButtonState;
}

void updateStateMachine() {
  unsigned long currentTime = millis();
  unsigned long elapsedTime = currentTime - stateStartTime;

  switch (currentState) {
    case IDLE:
      if (buttonPressed) {
        startState(POMODORO_1);
        buttonPressed = false;
      }
      break;

    case POMODORO_1:
      if (elapsedTime >= POMODORO_DURATION) {
        startState(BREAK_1);
      }
      break;

    case BREAK_1:
      if (elapsedTime >= SHORT_BREAK_DURATION) {
        startState(POMODORO_2);
      }
      break;

    case POMODORO_2:
      if (elapsedTime >= POMODORO_DURATION) {
        startState(BREAK_2);
      }
      break;

    case BREAK_2:
      if (elapsedTime >= SHORT_BREAK_DURATION) {
        startState(POMODORO_3);
      }
      break;

    case POMODORO_3:
      if (elapsedTime >= POMODORO_DURATION) {
        startState(BREAK_3);
      }
      break;

    case BREAK_3:
      if (elapsedTime >= SHORT_BREAK_DURATION) {
        startState(POMODORO_4);
      }
      break;

    case POMODORO_4:
      if (elapsedTime >= POMODORO_DURATION) {
        startState(LONG_BREAK);
      }
      break;

    case LONG_BREAK:
      if (elapsedTime >= LONG_BREAK_DURATION) {
        startState(IDLE);
      } else if (buttonPressed) {
        // Allow restarting during long break
        startState(POMODORO_1);
        buttonPressed = false;
      }
      break;
  }
}

void startState(State newState) {
  currentState = newState;
  stateStartTime = millis();

  // Debug output
  Serial.print("Entering state: ");
  Serial.println(getStateName(newState));
}

void updateLEDs() {
  // Turn off all LEDs first
  for (int i = 0; i < 5; i++) {
    digitalWrite(LED_PINS[i], LOW);
  }

  // Turn on appropriate LEDs based on state
  switch (currentState) {
    case IDLE:
      // All LEDs off
      break;

    case POMODORO_1:
      digitalWrite(LED_PINS[0], HIGH);
      break;

    case BREAK_1:
      // All LEDs off during break
      break;

    case POMODORO_2:
      digitalWrite(LED_PINS[0], HIGH);
      digitalWrite(LED_PINS[1], HIGH);
      break;

    case BREAK_2:
      // All LEDs off during break
      break;

    case POMODORO_3:
      digitalWrite(LED_PINS[0], HIGH);
      digitalWrite(LED_PINS[1], HIGH);
      digitalWrite(LED_PINS[2], HIGH);
      break;

    case BREAK_3:
      // All LEDs off during break
      break;

    case POMODORO_4:
      digitalWrite(LED_PINS[0], HIGH);
      digitalWrite(LED_PINS[1], HIGH);
      digitalWrite(LED_PINS[2], HIGH);
      digitalWrite(LED_PINS[3], HIGH);
      break;

    case LONG_BREAK:
      digitalWrite(LED_PINS[4], HIGH); // Green LED only
      break;
  }
}

String getStateName(State state) {
  switch (state) {
    case IDLE: return "IDLE";
    case POMODORO_1: return "POMODORO_1";
    case BREAK_1: return "BREAK_1";
    case POMODORO_2: return "POMODORO_2";
    case BREAK_2: return "BREAK_2";
    case POMODORO_3: return "POMODORO_3";
    case BREAK_3: return "BREAK_3";
    case POMODORO_4: return "POMODORO_4";
    case LONG_BREAK: return "LONG_BREAK";
    default: return "UNKNOWN";
  }
}
