// Proyek 004 - Lampu Lalu Lintas Mini
// Board: NodeMCU ESP8266 V3 | Dashboard: klenik.ichibot.id
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// ===== ISI DULU =====
const char* WIFI_NAMA = "nama-wifi-kamu";
const char* WIFI_PASS = "password-wifi-kamu";

// topic MQTT: ganti budi1234 dengan KODE-mu (sama dengan di dashboard Klenik)
const char* TOPIK_LAMPU    = "ichibot/budi1234/p004/lampu";
const char* TOPIK_OTOMATIS = "ichibot/budi1234/p004/otomatis";
const char* TOPIK_HIJAU    = "ichibot/budi1234/p004/hijau";
const char* TOPIK_DARURAT  = "ichibot/budi1234/p004/darurat";

const char* BROKER = "mqtt.ichibot.id";
WiFiClient wifi;
PubSubClient mqtt(wifi);
const int MERAH = D1, KUNING = D2, HIJAU = D5;
bool otomatis = true;
int detikHijau = 5;                   // lama lampu hijau, diatur dari slider
int fase = 0;                         // 0 merah, 1 hijau, 2 kuning
unsigned long mulai = 0;

void nyalakan(int f) {
  fase = f;
  mulai = millis();
  digitalWrite(MERAH, f == 0);
  digitalWrite(HIJAU, f == 1);
  digitalWrite(KUNING, f == 2);
  const char* nama[] = {"MERAH", "HIJAU", "KUNING"};
  mqtt.publish(TOPIK_LAMPU, nama[f]);
}

void pesanMasuk(char* t, byte* isi, unsigned int panjang) {
  String topik = t, p;
  for (unsigned int i = 0; i < panjang; i++) p += (char)isi[i];
  if (topik == TOPIK_OTOMATIS) otomatis = (p == "ON");
  else if (topik == TOPIK_HIJAU) detikHijau = constrain(p.toInt(), 2, 30);
  else if (topik == TOPIK_DARURAT && p == "ON") { otomatis = false; nyalakan(0); }
}

void langganan() {
  mqtt.subscribe(TOPIK_OTOMATIS);
  mqtt.subscribe(TOPIK_HIJAU);
  mqtt.subscribe(TOPIK_DARURAT);
}

void sambungWiFi() {
  WiFi.begin(WIFI_NAMA, WIFI_PASS);
  Serial.print("WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" OK, IP " + WiFi.localIP().toString());
}

void sambungMQTT() {
  while (!mqtt.connected()) {
    if (mqtt.connect(WiFi.macAddress().c_str())) {
      Serial.println("Terhubung ke Klenik");
      langganan();
    } else {
      Serial.println("Broker gagal, coba lagi 3 detik");
      delay(3000);
    }
  }
}
void setup() {
  Serial.begin(115200);
  pinMode(MERAH, OUTPUT); pinMode(KUNING, OUTPUT); pinMode(HIJAU, OUTPUT);
  sambungWiFi();
  mqtt.setServer(BROKER, 1883);
  mqtt.setCallback(pesanMasuk);
  nyalakan(0);
}

void loop() {
  if (!mqtt.connected()) sambungMQTT();
  mqtt.loop();
  if (!otomatis) return;

  unsigned long lama[] = {5000, (unsigned long)detikHijau * 1000, 2000};
  if (millis() - mulai >= lama[fase]) {
    int urutan[] = {1, 2, 0};          // merah -> hijau -> kuning -> merah
    nyalakan(urutan[fase]);
  }
}
