#include <WiFi.h>
#include <MQTT.h>
#include "RTClib.h"

WiFiClient client;
MQTTClient MQTTclient;
RTC_DS1307 rtc;

#define LDR_PIN 34

const float GAMMA = 0.7;
const float RL10 = 50;


int lamp = 23;
int electricDevice = 2;
int inputMovePin = 35;
int pirState = LOW;  
int moveVal = 0;

int turnOnHour = 0;
int turnOnMinute = 0;
int turnOffHour = 0;
int turnOffMinute = 0;
int Brightness = 255;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

float LDRvalue(int analogValue){
  analogValue = map(analogValue, 4095, 0, 1024, 0);
  float voltage = analogValue / 1024. * 5;
  float resistance = 2000 * voltage / (1 - voltage / 5);
  float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));

  return lux;
}

void RtcCheck(DateTime now){
  Serial.print("Current time: ");
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(" (");
  Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
  Serial.print(") ");
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();
}

void messageReceived(String &topic, String &payload) {
  
  Serial.println("Received MQTT message:");
  Serial.println("Topic: " + topic + ", Payload: " + payload);

  if (topic == "home/schedule") {
     
    int commaIndex1 = payload.indexOf(',');
    int commaIndex2 = payload.indexOf(',', commaIndex1 + 1);
    int commaIndex3 = payload.indexOf(',', commaIndex2 + 1);

    
    turnOnHour = payload.substring(0, commaIndex1).toInt();
    turnOnMinute = payload.substring(commaIndex1 + 1, commaIndex2).toInt();
    turnOffHour = payload.substring(commaIndex2 + 1, commaIndex3).toInt();
    turnOffMinute = payload.substring(commaIndex3 + 1).toInt();

    Serial.println(turnOnHour);
    Serial.println(turnOnMinute);
    Serial.println(turnOffHour);
    Serial.println(turnOffMinute);
  } else if (topic == "home/brightness") {
    Brightness = payload.toInt();
  }else if (topic == "home/electric/switch1"){
    if(payload == "2"){
      digitalWrite(electricDevice, HIGH);
    }else{
      digitalWrite(electricDevice, LOW);
    }
  }else if(topic == "notes"){
    //notes
  }

 
}

void setup() {
  pinMode(lamp, OUTPUT);
  pinMode(electricDevice, OUTPUT);
  pinMode(inputMovePin, INPUT);
  pinMode(LDR_PIN, INPUT);

  Serial.begin(9600);

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
  }else {
    DateTime now = rtc.now();
    RtcCheck(now);
  }

  Serial.print("Connecting to WiFi");
  WiFi.begin("Wokwi-GUEST", "");

  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print(".");
  }
  Serial.println("Connected to WiFi!");

  MQTTclient.begin("public.cloud.shiftr.io", 1883, client);
  MQTTclient.onMessage(messageReceived);
  if (MQTTclient.connect("Babkov", "public", "public")) 
  {
    Serial.println("Connected to MQTT broker.");
  }
  else
  {
    Serial.println("Connection to MQTT broker failed.");
  }
    MQTTclient.subscribe("home/schedule");
    MQTTclient.subscribe("home/brightness");
    MQTTclient.subscribe("home/electric/switch1");
    MQTTclient.subscribe("notes");
}


void loop() {
  MQTTclient.loop();
  MQTTclient.onMessage(messageReceived);
  float lux = LDRvalue(analogRead(LDR_PIN));
  moveVal = digitalRead(inputMovePin);
  DateTime now = rtc.now();
  bool withinTimeRange = false;
if (turnOnHour == 0 && turnOnMinute == 0 && turnOffHour == 0 && turnOffMinute == 0) {
  withinTimeRange = true;
}
  else if (
  (now.hour() > turnOnHour || (now.hour() == turnOnHour && now.minute() >= turnOnMinute)) &&
  (now.hour() < turnOffHour || (now.hour() == turnOffHour && now.minute() < turnOffMinute))
) {
  withinTimeRange = true;
} else if (
  (now.hour() < turnOnHour || (now.hour() == turnOnHour && now.minute() < turnOnMinute)) ||
  (now.hour() > turnOffHour || (now.hour() == turnOffHour && now.minute() >= turnOffMinute))
) {
  withinTimeRange = false;
} 

//     Serial.println(turnOnHour);
//     Serial.println(turnOnMinute);
//     Serial.println(turnOffHour);
//     Serial.println(turnOffMinute);
if (withinTimeRange) {
  if (moveVal == HIGH) {          
    if(lux<=50 && lux > 25 )  {
      Serial.println("Room: Dark!");
      Serial.println(lux);
      analogWrite(lamp, (Brightness*0.25));
    }else if(lux<25){
      analogWrite(lamp, Brightness);
    }
    else {
      analogWrite(lamp, 0);
      Serial.println("Room: Light!");
      Serial.println(lux);
      Serial.println("No need to turn the lamp on");
    }
      
    if (pirState == LOW) {
      
      Serial.println("Motion detected!");
      
      pirState = HIGH;
    }
  } else {
    analogWrite(lamp, 0);
    if (pirState == HIGH) {
      Serial.println("Motion ended!");
      
      pirState = LOW;
    }
  }
}else{
  analogWrite(lamp, 0);
}
  delay(500);
}
GND5VSDASCLSQWRTCDS1307+