#include <Arduino.h>
#include <TFT_eSPI.h>
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <EEPROM.h>
#include <AsyncTCP.h>
#include <SD.h>

#include "color.h"

void launchWiFiConfig();

// Read WiFi credentials from EEPROM
#define WIFI_SSID_ADDR 0
#define WIFI_PASS_ADDR 64
#define WIFI_MAX_LEN 32

#define DEBUG

#ifdef DEBUG
char output[80];
#define DEBUG_MSG(...)  snprintf(output,80, __VA_ARGS__ );   \
  Serial.println(output);
#else
#define DEBUG_MSG(...)
#endif

/* tft */
#define TFT_BL 21
TFT_eSPI tft = TFT_eSPI();

char wifi_ssid[WIFI_MAX_LEN];
char wifi_pass[WIFI_MAX_LEN];

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

    DEBUG_MSG("CYD DCC mouse Demo");
    // Turn on backlight and initialize TFT
    pinMode(TFT_BL, OUTPUT);
    digitalWrite(TFT_BL, HIGH); // Backlight ON
    DEBUG_MSG("Backlight ON");
    tft.init();
    DEBUG_MSG("TFT init done");

    DEBUG_MSG("Rotation set");

    // Print hello world on tft
    tft.fillScreen(COLOR_BLACK);
    tft.setTextColor(COLOR_WHITE);
    tft.setTextSize(1);
    tft.setCursor(10, 10);
    tft.println("Initialize Network...");
      
    DEBUG_MSG("Reading WiFi credentials from EEPROM");
    EEPROM.begin(128);
    for (int i = 0; i < WIFI_MAX_LEN; i++) {
      wifi_ssid[i] = EEPROM.read(WIFI_SSID_ADDR + i);
      wifi_pass[i] = EEPROM.read(WIFI_PASS_ADDR + i);
    }
    wifi_ssid[WIFI_MAX_LEN-1] = '\0';
    wifi_pass[WIFI_MAX_LEN-1] = '\0';

    bool ssid_found = strlen(wifi_ssid) > 0 && wifi_ssid[0] != 0xFF;
    bool pass_found = strlen(wifi_pass) > 0 && wifi_pass[0] != 0xFF;

    if (!ssid_found || !pass_found) 
    {
        DEBUG_MSG("WiFi credentials not found in EEPROM");
        tft.setCursor(10, 25);
        tft.setTextColor(COLOR_ORANGE);
        tft.println("WiFi credentials missing!");
        tft.setCursor(10, 40);
        tft.setTextColor(COLOR_YELLOW);
        tft.println("Please connect to CYD_Config AP"); 
        tft.setCursor(10, 55); 
        tft.println("and set WiFi credentials");
        launchWiFiConfig(); // Function to start WiFi configuration mode (not implemented here)

    } else {
      // Ok connect to WiFi 
      tft.setCursor(60, 10); 
      tft.setTextColor(COLOR_GREEN); 
      tft.println("OK");
      DEBUG_MSG("WiFi SSID: %s", wifi_ssid);
      DEBUG_MSG("WiFi PASS: %s", wifi_pass);
    }
    // Try to open SD card and read content
    if (!SD.begin()) {
        tft.println("SD Card not found!");
        while (1); // or handle error as needed
    }
    if (!SD.exists("/loco")) {
        tft.println("loco/ folder not found!");
        while (1); // or handle error as needed
    }

}

void loop() {
//   tft.fillScreen(TFT_PURPLE);
//   Serial.println("RED");
//   delay(1000);
//   tft.fillScreen(TFT_GREEN);
//   Serial.println("GREEN");
//   delay(1000);
//   tft.fillScreen(TFT_YELLOW);
//   Serial.println("BLUE");
//   delay(1000);
//   tft.fillScreen(TFT_BLACK);
//   Serial.println("BLACK");
//   delay(1000);
//   tft.fillScreen(TFT_WHITE);
//   Serial.println("WHITE");
//   delay(1000);
}

/** 
 * launchWiFiConfig() - Placeholder function to start WiFi configuration mode
 * In a real implementation, this would start an access point and web server to allow the user
 * to enter their WiFi credentials through a web interface. For this demo, it's just a placeholder.
 */
void launchWiFiConfig() 
{
    // Start WiFi in AP mode, set up a web server, and handle incoming connections to save new credentials to EEPROM
    WiFi.softAP("CYD_Config", "12345678");
    IPAddress myIP = WiFi.softAPIP();
    DEBUG_MSG("AP IP address: %s", myIP.toString().c_str());
      AsyncWebServer server(80);
    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
      String html = "<html><body><h2>WiFi Config</h2>"
        "<form action='/save' method='post'>"
        "SSID: <input name='ssid'><br>"
        "Password: <input name='pass' type='password'><br>"
        "<input type='submit' value='Save'></form></body></html>";
      request->send(200, "text/html", html);
    });
    server.on("/save", HTTP_POST, [](AsyncWebServerRequest *request){
      String ssid, pass;
      if (request->hasParam("ssid", true)) ssid = request->getParam("ssid", true)->value();
      if (request->hasParam("pass", true)) pass = request->getParam("pass", true)->value();
      for (int i = 0; i < WIFI_MAX_LEN; i++) {
        EEPROM.write(WIFI_SSID_ADDR + i, i < ssid.length() ? ssid[i] : 0);
        EEPROM.write(WIFI_PASS_ADDR + i, i < pass.length() ? pass[i] : 0);
      }
      EEPROM.commit();
      request->send(200, "text/html", "<html><body>Saved! Reboot device.</body></html>");
    });
    server.begin();
    tft.setCursor(10, 120);
    tft.setTextColor(COLOR_CYAN);
    tft.println("Connect to CYD_Config AP");
    tft.setCursor(10, 135);
    tft.println("Open 192.168.4.1 in browser");
    while (true) { delay(1000); }
}
