#include "WiFi.h"
#include <HTTPClient.h>
#include <ArduinoJson.h>

#include <DS1307RTC.h>
#include <TimeLib.h>

#include "lcdSymbols.h"
#include "Pins.h"

#include "MainLight.h"
#include "NightLight.h"
#include "AlarmClock.h"
#include "Display.hpp"
#include "SetTime.hpp"


const char* ssid = "Wokwi-GUEST";
const char* password = "";


MainLight M_Light(MAIN_LIGHT);
NightLight N_Light(NIGHT_LIGHT);
AlarmClock Alarm(ALARM_RELAY, ALARM_PIN);
Display MainDisplay(BUTTON_UP, BUTTON_DOWN, BUTTON_L, BUTTON_R, BUTTON_MENU);



void setup() {
  Serial.begin(115200);

  pinMode(BUTTON_LIGHT, INPUT);
  pinMode(MOTION_SENS, INPUT);

  lcd.init();
  lcd.backlight();
  // Не совсем понял как сделать правильно
  // Если закидывать эти строчки в конструктор дисплея,
  // то начинает жутко лагать
  lcd.createChar(0, up);
  lcd.createChar(1, down);
  lcd.createChar(2, yes);
  lcd.createChar(3, no);
  lcd.createChar(4, lightBulbOn);
  lcd.createChar(5, lightBulbOff);
  lcd.createChar(6, menu);
  lcd.createChar(7, back);

  Alarm.Time[0] = 8;
  Alarm.Time[1] = 15;


  WiFi.begin(ssid, password);
  int i = 0;
  while (WiFi.status() != WL_CONNECTED) {
    if(i == 10) break;
    i++;
    delay(1000);    
    Serial.println("Connecting to Wi-Fi...");
  }
  if(WiFi.status() == WL_CONNECTED){
    Serial.println("Wi-Fi connection is established!");
  }
  else{
    Serial.println("Couldn't connect to Wi-Fi!");
  }
  

  time_t Time = GetUnixTime();
  Serial.println(Time);
  if(Time >= 0){
    RTC.set(Time);
    setSyncProvider(RTC.get);   // the function to get the time from the RTC
  }
  else{
    setSyncProvider(0);
    setTime(1702537200);    
  }
}

void loop()
{
  static uint32_t currentTime = RTC.get();
  static uint32_t newTime;

  M_Light.ButtonControl(BUTTON_LIGHT);

  if(digitalRead(MOTION_SENS) == HIGH || M_Light.MotionDetected || N_Light.MotionDetected){
    if(M_Light.IsDaytime(hour(), minute()) && M_Light.IsOnIfMotion){
      M_Light.MotionControl();
    }
    else if(N_Light.IsNighttime(hour(), minute()) && N_Light.IsOnIfMotion){
      N_Light.MotionControl();
    }
  }


  if(Alarm.Enabled){
    if(Alarm.IsAlarmTime(hour(), minute()) || Alarm.CurrentState == HIGH){
      Alarm.Exec();
    }
  }

  
  MainDisplay.ButtonMenu();
  
  if(MainDisplay.GetState() == STATE_IDLE){ // Если в состоянии покоя - выводим время
    MainDisplay.PrintTime(MAIN_LIGHT);
  }
  else if(MainDisplay.GetState() == STATE_MENU){ // Если нажали на кнопку меню - отобразить список
    MainDisplay.PrintMenu();    
  }
  else if(MainDisplay.GetState() == STATE_EDIT){  // Если нажали на кнопку влево или вправо
    switch (MainDisplay.GetCurrentItem()){  // Смотрим на каком пункте меню сейчас и выводим параметр
      case MENU_NULL:
        break;
      case NIGHT_SENS:
        MainDisplay.PrintParam_Bool(N_Light.IsOnIfMotion);
        break;
      case NIGHT_DUR:
        MainDisplay.PrintParam_Duration(N_Light.DurTime, 10, 60);
        break;
      case MAIN_SENS:
        MainDisplay.PrintParam_Bool(M_Light.IsOnIfMotion);
        break;
      case MAIN_DUR:
        MainDisplay.PrintParam_Duration(M_Light.DurTime, 10, 600);
        break;
      case ALARM_TIME:      
        MainDisplay.PrintParam_Time(Alarm.Time[0], Alarm.Time[1]);      
        break;
      case ALARM_ONOFF:
        MainDisplay.PrintParam_Bool(Alarm.Enabled);
        break;
      case ALARM_DUR:
        MainDisplay.PrintParam_Duration(Alarm.DurTime, 10, 600);
        break;
      case SSID:        
        MainDisplay.PrintParam_Text(ssid);
        break;
      case PASS:
        MainDisplay.PrintParam_Text(password);
        break;
      case SET_TIME:
        newTime = currentTime;
        MainDisplay.PrintParam_DateTime(hour(), minute(), second(), day(), month(), year(), newTime);
        if(currentTime != newTime){
          currentTime = newTime;
          setTime(currentTime);          
        }
        break;
      default:
        break;                                                                              
    }
  }
  


}



GND5VSDASCLSQWRTCDS1307+
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module