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

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
RTC_DS1307 rtc;

const int buttonPin1 = 2;
const int buttonPin2 = 3;
const int buttonPin3 = 4;
const int relayPin = 7;

unsigned long previousMillis = 0;
const unsigned long interval = 1000;

unsigned long lastButtonPressTime = 0; // Час останнього натискання кнопки

enum ScreenType { MAIN_SCREEN, TIMER_SCREEN };
ScreenType currentScreen = MAIN_SCREEN;
DateTime timerStartTime; // Час початку таймера
DateTime timerEndTime; // Час завершення таймера
bool timerActive = false; // Флаг активності таймера
bool settingEndTime = false;
bool changingTimeMode = false;
int selectedParameter = 0; // 0 - години, 1 - хвилини, 2 - секунди
int blinkCounter = 0;

void setup() {
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, HIGH);

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }
  
  if (!rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (!rtc.isrunning()) {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
}

void loop() {
  DateTime now = rtc.now();
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    display.clearDisplay();
    display.setTextSize(2);
    display.setTextColor(WHITE);

    switch (currentScreen) {
      case MAIN_SCREEN:
        // Виведення годин у форматі ГГ:ХХ:СС
        display.setCursor(0, 0);
        if (now.hour() < 10)
          display.print('0');
        display.print(now.hour(), DEC);
        display.print(':');
        if (now.minute() < 10)
          display.print('0');
        display.print(now.minute(), DEC);
        display.print(':');
        if (now.second() < 10)
          display.print('0');
        display.print(now.second(), DEC);
        break;

      case TIMER_SCREEN:
        if (timerActive) {
          // Виведення часу ввімкнення і вимкнення реле
          display.setCursor(0, 0);
          display.print("T.ON= ");
          display.setCursor(0, 15);
          display.print(timerStartTime.hour(), DEC);
          display.print(':');
          if (timerStartTime.minute() < 10)
            display.print('0');
          display.print(timerStartTime.minute(), DEC);
          display.print(':');
          if (timerStartTime.second() < 10)
            display.print('0');
          display.print(timerStartTime.second(), DEC);

          if (timerEndTime.unixtime() != 0) {
            display.setCursor(0, 30);
            display.print("T.OFF= ");
            display.setCursor(0, 45);
            display.print(timerEndTime.hour(), DEC);
            display.print(':');
            if (timerEndTime.minute() < 10)
              display.print('0');
            display.print(timerEndTime.minute(), DEC);
            display.print(':');
            if (timerEndTime.second() < 10)
              display.print('0');
            display.print(timerEndTime.second(), DEC);
          }
        } else {
          // Таймер завершено, перехід на основний екран
          currentScreen = MAIN_SCREEN;
        }
        if (millis() - lastButtonPressTime > 10000) {
          currentScreen = MAIN_SCREEN;
        }
        break;
    }

    // Виведення екрану зміни часу таймера
    if (changingTimeMode) {
      if (blinkCounter < 10) {
        display.setTextColor(WHITE, BLACK);
      } else {
        display.setTextColor(BLACK, WHITE);
      }
      blinkCounter = (blinkCounter + 1) % 20;

      display.setCursor(0, 0);
      display.print("T.ON= ");
      display.setCursor(0, 15);
      display.print(timerStartTime.hour(), DEC);
      display.print(':');
      display.print(timerStartTime.minute() < 10 ? '0' : ' ');
      display.print(timerStartTime.minute(), DEC);
      display.print(':');
      display.print(timerStartTime.second() < 10 ? '0' : ' ');
      display.print(timerStartTime.second(), DEC);

      display.setCursor(0, 30);
      display.print("T.OFF= ");
      display.setCursor(0, 45);
      display.print(timerEndTime.hour(), DEC);
      display.print(':');
      display.print(timerEndTime.minute() < 10 ? '0' : ' ');
      display.print(timerEndTime.minute(), DEC);
      display.print(':');
      display.print(timerEndTime.second() < 10 ? '0' : ' ');
      display.print(timerEndTime.second(), DEC);
    }

    display.display();
  }

  // Опитування стану кнопки K1
  if (digitalRead(buttonPin1) == HIGH) {
    // Кнопку натиснуто
    unsigned long buttonPressTime = millis();

    // Перевірка тривалості натискання (менше 1 сек)
    while (digitalRead(buttonPin1) == HIGH && millis() - buttonPressTime < 1000) {
      // Очікування
    }

    if (millis() - buttonPressTime < 1000) {
      // Коротке натискання
      lastButtonPressTime = millis(); // Оновлення часу останнього натискання кнопки

      if (currentScreen == MAIN_SCREEN) {
        // Перехід на "екран таймера"
        currentScreen = TIMER_SCREEN;
        timerStartTime = now; // Запуск таймера
        timerActive = true;
        digitalWrite(relayPin, HIGH);
      } else if (currentScreen == TIMER_SCREEN) {
        // Повернення на "основний екран"
        currentScreen = MAIN_SCREEN;
        timerEndTime = now;
        timerActive = false; // Вимкнення таймера
        digitalWrite(relayPin, LOW);
      }
    } else if (millis() - buttonPressTime > 1000 && millis() - buttonPressTime < 3000) {
      // Тривале натискання (>1сек), перехід в режим зміни часу таймера
      changingTimeMode = !changingTimeMode;
      blinkCounter = 0;
    } else if (millis() - buttonPressTime > 3000 && changingTimeMode) {
      // Тривале натискання (>3сек) в режимі зміни часу таймера, зміна параметрів таймера
      if (selectedParameter == 0) {
        // Зміна годин
        timerStartTime = timerStartTime + TimeSpan(0, 1, 0, 0);
      } else if (selectedParameter == 1) {
        // Зміна хвилин
        timerStartTime = timerStartTime + TimeSpan(0, 0, 1, 0);
      } else if (selectedParameter == 2) {
        // Зміна секунд
        timerStartTime = timerStartTime + TimeSpan(0, 0, 0, 1);
      } else if (selectedParameter == 3) {
        // Зміна годин
        timerEndTime = timerEndTime + TimeSpan(0, 1, 0, 0);
      } else if (selectedParameter == 4) {
        // Зміна хвилин
        timerEndTime = timerEndTime + TimeSpan(0, 0, 1, 0);
      } else if (selectedParameter == 5) {
        // Зміна секунд
        timerEndTime = timerEndTime + TimeSpan(0, 0, 0, 1);
      }
    }
  }

  // Додано опитування стану кнопок K2 і K3 в режимі зміни часу таймера
  if (changingTimeMode) {
    if (digitalRead(buttonPin2) == HIGH) {
      // Кнопку K2 натиснуто в режимі зміни часу таймера
      selectedParameter = (selectedParameter + 1) % 6;
      delay(200); // Затримка для уникнення спрацювання декількох разів при утримуванні кнопки
    }

    if (digitalRead(buttonPin3) == HIGH) {
      // Кнопку K3 натиснуто в режимі зміни часу таймера
      selectedParameter = (selectedParameter + 5) % 6;
      delay(200); // Затримка для уникнення спрацювання декількох разів при утримуванні кнопки
    }
  }

  // Додано умову для спрацювання реле згідно із заданим інтервалом
  if (now >= timerStartTime && now <= timerEndTime) {
    digitalWrite(relayPin, HIGH); // Спрацювання реле
  } else {
    digitalWrite(relayPin, LOW); // Реле вимкнено
  }
}
GND5VSDASCLSQWRTCDS1307+
NOCOMNCVCCGNDINLED1PWRRelay Module