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

RTC_DS3231 rtc;

// ================= PIN CONFIG =================
const int ledPin = 4;
const int relayPin = 8;
const int buzzerPin = 9;
const int resetPin = 2;

// ================= TIMER =================
// TEST MODE (60 sec)
const uint32_t TIME_LIMIT = 60UL;

// PRODUCTION (380 days)
// const uint32_t TIME_LIMIT = 32832000UL;

DateTime startTime;
bool timerRunning = false;
bool timerDone = false;

// buzzer + led toggle
unsigned long lastToggle = 0;
bool state = false;

// EEPROM address
const int addr = 0;

void setup() {

  pinMode(ledPin, OUTPUT);
  pinMode(relayPin, OUTPUT);
  pinMode(buzzerPin, OUTPUT);
  pinMode(resetPin, INPUT_PULLUP);

  digitalWrite(ledPin, LOW);
  digitalWrite(relayPin, LOW);
  digitalWrite(buzzerPin, LOW);

  rtc.begin();

  startTimer();
}

void loop() {

  // ================= RESET BUTTON =================
  if (digitalRead(resetPin) == LOW) {
    delay(50);
    if (digitalRead(resetPin) == LOW) {
      resetSystem();
      while (digitalRead(resetPin) == LOW);
    }
  }

  // ================= TIMER RUNNING =================
  if (timerRunning) {

    DateTime now = rtc.now();
    uint32_t elapsed = now.unixtime() - startTime.unixtime();

    if (elapsed >= TIME_LIMIT) {

      timerRunning = false;
      timerDone = true;

      // OUTPUT OFF after time complete
      digitalWrite(relayPin, HIGH);
    }
  }

  // ================= AFTER TIMER DONE =================
  if (timerDone) {

    DateTime now = rtc.now();

    // Daily alarm window 7:30–7:40 PM
    if (now.hour() == 19 && now.minute() >= 30 && now.minute() < 40) {

      if (millis() - lastToggle >= 300) {

        lastToggle = millis();
        state = !state;

        // LED BLINK
        digitalWrite(ledPin, state);

        // BUZZER (ACTIVE + PASSIVE SUPPORT)
        tone(buzzerPin, state ? 2000 : 0);
      }

    } else {
      digitalWrite(ledPin, LOW);
      noTone(buzzerPin);
    }
  }
}

// ================= START TIMER =================
void startTimer() {

  uint32_t savedTime;
  EEPROM.get(addr, savedTime);

  if (savedTime == 0xFFFFFFFF || savedTime == 0) {
    savedTime = rtc.now().unixtime();
    EEPROM.put(addr, savedTime);
  }

  startTime = DateTime(savedTime);

  timerRunning = true;
  timerDone = false;

  digitalWrite(relayPin, LOW);
  digitalWrite(ledPin, LOW);
  noTone(buzzerPin);
}

// ================= RESET SYSTEM =================
void resetSystem() {

  uint32_t newTime = rtc.now().unixtime();
  EEPROM.put(addr, newTime);

  startTime = DateTime(newTime);

  timerRunning = true;
  timerDone = false;

  state = false;

  digitalWrite(relayPin, LOW);
  digitalWrite(ledPin, LOW);
  noTone(buzzerPin);
}