
#include <logger.h>
#include "wifi.hpp"
#include "mqtt.hpp"
#include "config.hpp"
#include "lorahandler.hpp"
#include "display.hpp"
#include <WiFi.h>
#include <ArduinoJson.h>

Config config;
WiFiServer server(80);
WiFiClient wclient;
Mqtt mqtt(wclient); 
LoraHandler lora; 
Display display;
logging::Logger logger;

#define TRIGGER_PIN 0
void checkButton();

bool portalRunning = false;

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

#ifndef DEBUG
  logger.setDebugLevel(logging::LoggerLevel::LOGGER_LEVEL_INFO);
#endif
  pinMode(TRIGGER_PIN, INPUT);

  WiFi.mode(WIFI_STA);
  config = Config();

  while (!config.isConfigLoaded)
  {
    delay(10); 
    logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "MAIN", "COnfig not loaded yet...");
  }
  delay(100); 
  display.setup_display();
  display.show_display("STARTUP");
  setupWifi("island_temp", false);

  mqtt.mqttSetup();
  lora.setup();
  delay(5*1000); // Show text in 5s
  display.cleanTFT();
}

void loop()
{
 ReceivedLoRaPacket packet = lora.receivePacket();
 
 // Process received LoRa packet
 if (!packet.text.isEmpty())
 {
    logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "MAIN", "Processing LoRa packet: %s", packet.text.c_str());
    
    // Try to parse JSON payload from sender
    JsonDocument doc;
    DeserializationError error = deserializeJson(doc, packet.text);
    
    if (!error) {
        float temp = doc["temp"] | 0.0;
        int battery = doc["battery"] | 0;
        int boot = doc["boot"] | 0;
        int update = doc["update"] | 0;
        
        logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "MAIN", "Parsed - Temp: %.2f, Battery: %d, Boot: %d, Update: %d", temp, battery, boot, update);
        
        // Publish to MQTT with Home Assistant format
        if (WiFi.status() == WL_CONNECTED) {
            mqtt.publishSensorData(temp, packet.rssi, battery);
        }
    } else {
        logger.log(logging::LoggerLevel::LOGGER_LEVEL_WARN, "MAIN", "Failed to parse JSON: %s", error.c_str());
    }
 }
 else
 {
    packet.rssi = 0;
    packet.snr = 0.0;
 }

  if (WiFi.status() == WL_CONNECTED) { // Check WiFi connection
    IPAddress ip = WiFi.localIP();
    String line0 = "IP: " + ip.toString();
    display.show_message(line0.c_str(), 0);
  } else {
    // Optional: Display message indicating WiFi not connected
    display.show_message("WiFi not connected", 0);
  }
  
  String line1 = "LoRa RSSI: " +  String(packet.rssi) + " dBm";
  display.show_message(line1.c_str(), 1);
  
  String line2 = "SNR: " + String(packet.snr, 1) + " dB";
  display.show_message(line2.c_str(), 2);
  
  display.show_message("Data received OK", 3);
  
  // Keep MQTT connection alive
  mqtt.mqttRun();
  
  sleep(5);
}


void checkButton()
{
  // check for button press
  if (digitalRead(TRIGGER_PIN) == LOW)
  {
    // poor mans debounce/press-hold, code not ideal for production
    delay(50);
    if (digitalRead(TRIGGER_PIN) == LOW)
    {
      logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Main", "Button Pressed once, wait 3s");
      // still holding button for 3000 ms
      delay(3000); // reset delay hold
      if (digitalRead(TRIGGER_PIN) == LOW)
      {
        logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Main", "Button Pressed, Starting Portal");
        wm.startWebPortal();
        portalRunning = true;
      }

      // start portal w delay
      logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Main", "Starting config portal");
      Serial.println("Starting config portal");
      wm.setConfigPortalTimeout(120);

      if (!wm.startConfigPortal("island_temp"))
      {
        logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Main", "failed to connect or hit timeout");
        delay(3000);
        // ESP.restart();
      }
      else
      {
        // if you get here you have connected to the WiFi
        logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Main", "connected...yeey :)");
      }
    }
  }
}
