#include <WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// Wifi.
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
// char auth[] = "IJ27LRmAvSsSweeqmhWJ32nRlrCOEOYl";

// MQTT Broker
const char* mqtt_broker = "broker.hivemq.com";
const int mqtt_port = 1883;
const char* mqtt_topic = "wokwi/esp32";
const char* clientID = "Wokwi_ESP32_Client"; // Use the same Client ID as your MQTT.fx setup if required

WiFiClient espClient;
PubSubClient mqtt_client(espClient);

// OLED display settings (using default I2C address 0x3C)
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

// Initialize WiFi
void setup_wifi() {
  delay(10);
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
}

// Callback function for receiving subscribed messages
void mqtt_callback(char* topic, byte* message, unsigned int length) {
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  // Print the incoming message to the OLED display
  for (unsigned int i = 0; i < length; i++) {
    display.write(message[i]);
  }
  display.display();
}

// Function to reconnect to the MQTT broker
void reconnect_mqtt() {
  while (!mqtt_client.connected()) {
    if (mqtt_client.connect(clientID)) {
      // Once connected, subscribe to the topic
      mqtt_client.subscribe(mqtt_topic);
    } else {
      delay(5000);
    }
  }
}

void setup() {
  // Start the OLED display
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.display();
  
  // Initialize WiFi and MQTT
  setup_wifi();
  mqtt_client.setServer(mqtt_broker, mqtt_port);
  mqtt_client.setCallback(mqtt_callback);
}

void loop() {
  if (!mqtt_client.connected()) {
    reconnect_mqtt();
  }
  mqtt_client.loop();

  // Publish a message every 10 seconds
  static unsigned long lastMillis = 0;
  if (millis() - lastMillis > 10000) {
    mqtt_client.publish(mqtt_topic, "Hello from Wokwi ESP32!");
    lastMillis = millis();
  }
}