#include <WiFi.h>
#include <WiFiClient.h>
#include <PubSubClient.h>

///########### configuração do wifi
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""
#define WIFI_CHANNEL 6
int status = WL_IDLE_STATUS;

///### configuração do LDR
#define LDR_PIN 34
const float GAMMA = 0.7;
const float RL10 = 33;
int valorAnterior = 0;
float lux = 0;

///########## configuração do MQTT
const char* mqtt_server = "test.mosquitto.org";
char* my_topic_SUB = "FIT/SUB";
char* my_topic_PUB = "FIT/PUB";

WiFiClient espClient;
PubSubClient client(espClient);

int contador = 1;
char mensagem[30];
unsigned long lastMillis = 0;

void setup() {
  Serial.begin(115200);
  Serial.println("Hello, ESP32!");

  pinMode(19, OUTPUT);  // Configura o pino do LED como saída
  pinMode(18, OUTPUT);  // Configura o pino alternativo como saída

  conectawifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop() {
  float luz = fotoresistor();

  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  delay(100);

  if (millis() - lastMillis > 15000) {
    lastMillis = millis();
    sprintf(mensagem, "%d", (int)luz);
    Serial.print("Mensagem enviada: ");
    Serial.println(mensagem);
    client.publish(my_topic_PUB, mensagem);
    Serial.print(contador);
    Serial.println("-Mensagem enviada com sucesso...");
    contador++;
  }
  delay(10);
}

void conectawifi() {
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD, WIFI_CHANNEL);
  Serial.print("Conectando ao WiFi ");
  Serial.print(WIFI_SSID);
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print(".");
  }
  Serial.println(" Conectado!");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

float fotoresistor() {
  int analogValue = analogRead(LDR_PIN);
  if (analogValue != valorAnterior) {
    float voltage = analogValue / 4096.0 * 3.3;
    float resistance = 2000 * voltage / (1 - voltage / 3.3);
    lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));

    Serial.print("Ambiente: ");
    if (lux > 400) {
      digitalWrite(18, HIGH);
      digitalWrite(19, LOW);
      Serial.println("Claro!");
    } else {
      digitalWrite(19, HIGH);
      digitalWrite(18, LOW);
      Serial.println("Escuro");
    }

    Serial.print("Luminosidade: ");
    Serial.println(lux);

    valorAnterior = analogValue;
  }
  return lux;
}

void callback(char* topic, byte* payload, unsigned int length) {
  String string;
  Serial.print("Chegou a mensagem [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    string += ((char)payload[i]);
  }
  Serial.print(string);
}

void reconnect() {
  while (!client.connected()) {
    Serial.print("Tentando conectar ao MQTT ...");
    if (client.connect("ESPClient")) {
      Serial.println("Conectado");
      client.subscribe(my_topic_SUB);
    } else {
      Serial.print("falhou, rc=");
      Serial.print(client.state());
      Serial.println(" Tente novamente em 5 segundos");
      delay(5000);
    }
  }
}