#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;                                                                              
    }
  }
  


}



esp:0
esp:2
esp:4
esp:5
esp:12
esp:13
esp:14
esp:15
esp:16
esp:17
esp:18
esp:19
esp:21
esp:22
esp:23
esp:25
esp:26
esp:27
esp:32
esp:33
esp:34
esp:35
esp:3V3
esp:EN
esp:VP
esp:VN
esp:GND.1
esp:D2
esp:D3
esp:CMD
esp:5V
esp:GND.2
esp:TX
esp:RX
esp:GND.3
esp:D1
esp:D0
esp:CLK
GND5VSDASCLSQWRTCDS1307+
rtc1:GND
rtc1:5V
rtc1:SDA
rtc1:SCL
rtc1:SQW
lcd1:GND
lcd1:VCC
lcd1:SDA
lcd1:SCL
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
btn2:1.l
btn2:2.l
btn2:1.r
btn2:2.r
btn3:1.l
btn3:2.l
btn3:1.r
btn3:2.r
btn4:1.l
btn4:2.l
btn4:1.r
btn4:2.r
bz1:1
bz1:2
led1:A
led1:C
pir1:VCC
pir1:OUT
pir1:GND
NOCOMNCVCCGNDINLED1PWRRelay Module
relay1:VCC
relay1:GND
relay1:IN
relay1:NC
relay1:COM
relay1:NO
NOCOMNCVCCGNDINLED1PWRRelay Module
relay3:VCC
relay3:GND
relay3:IN
relay3:NC
relay3:COM
relay3:NO
led3:A
led3:C
led4:A
led4:C
r1:1
r1:2
r2:1
r2:2
r3:1
r3:2
led2:A
led2:C
r4:1
r4:2
led5:A
led5:C
led6:A
led6:C
r5:1
r5:2
r6:1
r6:2
btn7:1.l
btn7:2.l
btn7:1.r
btn7:2.r
btn8:1.l
btn8:2.l
btn8:1.r
btn8:2.r