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

#include "DHTesp.h"   // Lib DHT22 para ESP
#include "widget.h"   // Conteúdo da página HTML com javascript

#define LED 15        // On board LED
#define DHT_PIN 11    // Pino do sensor DHT22

// SSID e senha do seu roteador WiFi
const char* SSID = "Wokwi-GUEST";
const char* PASSWORD = "";

float humidity, temperature;

DHTesp dht;

WebServer server(80); // Servidor na porta 80

void handleRoot() {
  String s = MAIN_page; // Lê o conteúdo da página HTML
  server.send(200, "text/html", s); // Envia página da web
}

void setup()
{
  Serial.begin(115200);

  dht.setup(DHT_PIN, DHTesp::DHT22); // Conecta o sensor DHT22 ao GPIO 15

  initWiFi();                       // Conecta ao seu roteador WiFi
  Serial.println("");

  // Onboard LED port direction output
  pinMode(LED, OUTPUT);

  reconnectWiFi();

  server.on("/", handleRoot);           // Esta é a página de exibição
  server.on("/weather", handleWeather); // Esta página é chamada por AJAX
  server.begin();                       // Inicia o servidor
  Serial.println("HTTP server started");
}

void loop()
{
  server.handleClient(); // Lida com as solicitações de clientes
}

void handleWeather() {
  int rain = map(random(1023), 0, 4095, 0, 100);

  // Create JSON data
  String data = "{\"rain\":\"" + String(rain) + "\", \"temperature\":\"" + String(temperature) + "\", \"humidity\":\"" + String(humidity) + "\"}";

  digitalWrite(LED, !digitalRead(LED)); // Alterna o LED na solicitação de dados AJAX
  server.send(200, "application/json", data); // Envia o valor da temperatura e umidade em JSON

  // Obtem os dados de temperatura e umidade após concluir a solicitação
  // Aguarde um tempo suficiente para comunicar com o cliente e evitar problemas
  delay(dht.getMinimumSamplingPeriod());

  // Obs.: Essa funcionalidade ainda não foi implementada, por isso o uso do random
  humidity = dht.getHumidity();
  temperature = dht.getTemperature();

  Serial.print("Humidity: ");
  Serial.println(humidity);
  Serial.print("Temperature: ");
  Serial.println(temperature); // dht.toFahrenheit(temperature));
  Serial.print("Rain: ");
  Serial.println(rain);
}

void initWiFi(void)
{
  delay(100);
  Serial.println("------Conexao WI-FI------");
  Serial.print("Conectando-se na rede: ");
  Serial.println(SSID);
  Serial.print("Aguarde");
  // Inicia e conecta-se na rede WI-FI desejada
  reconnectWiFi();
}

void reconnectWiFi(void)
{
  // Se já está conectado a rede WI-FI, apenas retorna
  // Caso contrário, são efetuadas tentativas de conexão
  if (WiFi.status() == WL_CONNECTED)
    return;

  WiFi.begin(SSID, PASSWORD); // Conecta na rede WI-FI

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

  Serial.println();
  Serial.print("Conectado com sucesso na rede: ");
  Serial.println(SSID);
  Serial.println("IP obtido: ");
  Serial.println(WiFi.localIP());
}