#define BLYNK_PRINT Serial
#define BLYNK_TEMPLATE_ID "TMPL6SDwaG6I0"
#define BLYNK_TEMPLATE_NAME "Traffic light by Thieu Quang"
#define BLYNK_AUTH_TOKEN "8MKkq6ab3XxXDlLmM0bZAcUSL8-1XqmH"
#define pinRed 12
#define pinYellow 27
#define pinGreen 25
#include <WiFi.h>
#include <WiFiClient.h>
#include <LiquidCrystal_I2C.h>
#include <BlynkSimpleEsp32.h>

BlynkTimer timer;
LiquidCrystal_I2C lcd(0x27, 16, 2);  // I2C address 0x27, 16 column and 2 rows

char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "Wokwi-GUEST";
char pass[] = "";

// Traffic light timing variables (in seconds)
int greenTime = 10;
int yellowTime = 3;
int redTime = 10;

// Function to update the traffic light status
void updateTrafficLight() {
  // Green
  digitalWrite(pinGreen, HIGH);

  lcd.setCursor(0, 0);
  lcd.print("Green:   ");
  for (int i = greenTime; i >= 0; i--) {
    lcd.setCursor(7, 0);
    lcd.print(i);
    delay(1000);
     // Clear the display before updating the next digit
    lcd.setCursor(0, 0);
    lcd.print("Green:   ");
  }
  digitalWrite(pinGreen, LOW);

  // Yellow
  digitalWrite(pinYellow, HIGH);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Yellow:  ");
  for (int i = yellowTime; i >= 0; i--) {
    lcd.setCursor(8, 0);
    lcd.print(i);
    delay(1000);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Yellow:  ");
  }
  digitalWrite(pinYellow, LOW);

  // Red
  digitalWrite(pinRed, HIGH);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Red:     ");
  for (int i = redTime; i >= 0; i--) {
    lcd.setCursor(7, 0);
    lcd.print(i);
    delay(1000);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Red:     ");
  }
  digitalWrite(pinRed, LOW);
}

BLYNK_CONNECTED(){
  Blynk.syncVirtual(V0);
  Blynk.syncVirtual(V1);
  Blynk.syncVirtual(V2);
}

BLYNK_WRITE(V0) {
  greenTime = param.asInt();
}

BLYNK_WRITE(V1) {
  yellowTime = param.asInt();
}

BLYNK_WRITE(V2) {
  redTime = param.asInt();
}

void setup() {
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  pinMode(pinRed, OUTPUT);
  pinMode(pinYellow, OUTPUT);
  pinMode(pinGreen, OUTPUT);

  // Initial state
  digitalWrite(pinRed, HIGH); // Red

  lcd.init( );
  lcd.backlight();
}


void loop() {
  Blynk.run();
  timer.run();
  updateTrafficLight();
}