#include "web_server.h"
#include <WebServer.h>
#include "wifi_manager.h"

static WebServer server(80);
static const SenderStatus *g_statuses = nullptr;
static uint8_t g_status_count = 0;
static WifiMqttConfig g_config;
static bool g_is_ap = false;

static String html_header(const String &title) {
  String h = "<!DOCTYPE html><html><head><meta charset='utf-8'><meta name='viewport' content='width=device-width,initial-scale=1'>";
  h += "<title>" + title + "</title></head><body>";
  h += "<h2>" + title + "</h2>";
  return h;
}

static String html_footer() {
  return "</body></html>";
}

static String render_sender_block(const SenderStatus &status) {
  String s;
  s += "<div style='margin-bottom:10px;padding:6px;border:1px solid #ccc'>";
  s += "<strong>" + String(status.last_data.device_id) + "</strong><br>";
  if (!status.has_data) {
    s += "No data";
  } else {
    s += "Energy: " + String(status.last_data.energy_total_kwh, 3) + " kWh<br>";
    s += "Power: " + String(status.last_data.total_power_w, 1) + " W<br>";
    s += "Battery: " + String(status.last_data.battery_voltage_v, 2) + " V (" + String(status.last_data.battery_percent) + ")";
  }
  s += "</div>";
  return s;
}

static void handle_root() {
  String html = html_header("DD3 Bridge Status");
  html += g_is_ap ? "<p>Mode: AP</p>" : "<p>Mode: STA</p>";

  if (g_statuses) {
    for (uint8_t i = 0; i < g_status_count; ++i) {
      html += render_sender_block(g_statuses[i]);
    }
  }

  html += "<p><a href='/wifi'>Configure WiFi/MQTT/NTP</a></p>";
  html += html_footer();
  server.send(200, "text/html", html);
}

static void handle_wifi_get() {
  String html = html_header("WiFi/MQTT Config");
  html += "<form method='POST' action='/wifi'>";
  html += "SSID: <input name='ssid' value='" + g_config.ssid + "'><br>";
  html += "Password: <input name='pass' type='password' value='" + g_config.password + "'><br>";
  html += "MQTT Host: <input name='mqhost' value='" + g_config.mqtt_host + "'><br>";
  html += "MQTT Port: <input name='mqport' value='" + String(g_config.mqtt_port) + "'><br>";
  html += "MQTT User: <input name='mquser' value='" + g_config.mqtt_user + "'><br>";
  html += "MQTT Pass: <input name='mqpass' type='password' value='" + g_config.mqtt_pass + "'><br>";
  html += "NTP Server 1: <input name='ntp1' value='" + g_config.ntp_server_1 + "'><br>";
  html += "NTP Server 2: <input name='ntp2' value='" + g_config.ntp_server_2 + "'><br>";
  html += "<button type='submit'>Save</button>";
  html += "</form>";
  html += html_footer();
  server.send(200, "text/html", html);
}

static void handle_wifi_post() {
  WifiMqttConfig cfg;
  cfg.ntp_server_1 = "pool.ntp.org";
  cfg.ntp_server_2 = "time.nist.gov";
  cfg.ssid = server.arg("ssid");
  cfg.password = server.arg("pass");
  cfg.mqtt_host = server.arg("mqhost");
  cfg.mqtt_port = static_cast<uint16_t>(server.arg("mqport").toInt());
  cfg.mqtt_user = server.arg("mquser");
  cfg.mqtt_pass = server.arg("mqpass");
  if (server.arg("ntp1").length() > 0) {
    cfg.ntp_server_1 = server.arg("ntp1");
  }
  if (server.arg("ntp2").length() > 0) {
    cfg.ntp_server_2 = server.arg("ntp2");
  }
  cfg.valid = true;
  wifi_save_config(cfg);
  server.send(200, "text/html", "<html><body>Saved. Rebooting...</body></html>");
  delay(1000);
  ESP.restart();
}

static void handle_sender() {
  if (!g_statuses) {
    server.send(404, "text/plain", "No senders");
    return;
  }
  String uri = server.uri();
  String device_id = uri.substring(String("/sender/").length());
  for (uint8_t i = 0; i < g_status_count; ++i) {
    if (device_id.equalsIgnoreCase(g_statuses[i].last_data.device_id)) {
      String html = html_header("Sender " + device_id);
      html += render_sender_block(g_statuses[i]);
      html += html_footer();
      server.send(200, "text/html", html);
      return;
    }
  }
  server.send(404, "text/plain", "Not found");
}

void web_server_set_config(const WifiMqttConfig &config) {
  g_config = config;
}

void web_server_begin_ap(const SenderStatus *statuses, uint8_t count) {
  g_statuses = statuses;
  g_status_count = count;
  g_is_ap = true;

  server.on("/", handle_root);
  server.on("/wifi", HTTP_GET, handle_wifi_get);
  server.on("/wifi", HTTP_POST, handle_wifi_post);
  server.on("/sender/", handle_sender);
  server.onNotFound([]() {
    if (server.uri().startsWith("/sender/")) {
      handle_sender();
      return;
    }
    server.send(404, "text/plain", "Not found");
  });
  server.begin();
}

void web_server_begin_sta(const SenderStatus *statuses, uint8_t count) {
  g_statuses = statuses;
  g_status_count = count;
  g_is_ap = false;

  server.on("/", handle_root);
  server.on("/sender/", handle_sender);
  server.on("/wifi", HTTP_GET, handle_wifi_get);
  server.on("/wifi", HTTP_POST, handle_wifi_post);
  server.onNotFound([]() {
    if (server.uri().startsWith("/sender/")) {
      handle_sender();
      return;
    }
    server.send(404, "text/plain", "Not found");
  });
  server.begin();
}

void web_server_loop() {
  server.handleClient();
}
