// Este código mezcla un captive portal con el 
// servidor asincrónico de ESP32 y el modulo
// SD para cargar archivos de forma nativa.
// Hasta el momento he probado .mp3 / .png como formatos 
// de stream para sonido e imagen. Requiere un index.html
// que cargue los archivos 
// importante descargar las librerias AsyncTCP.h y "ESPAsyncWebServer.h"


#include <DNSServer.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include "ESPAsyncWebServer.h"
#include "FS.h"
#include "SD.h"
#include "SPI.h"

DNSServer dnsServer;
AsyncWebServer server(80);

String user_name;
String proficiency;
bool name_received = false;
bool proficiency_received = false;

void initSDCard(){
  if(!SD.begin()){
    Serial.println("Card Mount Failed");
    return;
  }
  uint8_t cardType = SD.cardType();

  if(cardType == CARD_NONE){
    Serial.println("No SD card attached");
    return;
  }

 Serial.print("SD Card Type: ");
  if(cardType == CARD_MMC){
    Serial.println("MMC");
  } else if(cardType == CARD_SD){
    Serial.println("SDSC");
  } else if(cardType == CARD_SDHC){
    Serial.println("SDHC");
  } else {
    Serial.println("UNKNOWN");
  }
  uint64_t cardSize = SD.cardSize() / (1024 * 1024);
  Serial.printf("SD Card Size: %lluMB\n", cardSize);
}


//const char index_html[] PROGMEM = R"rawliteral(
//<!DOCTYPE HTML><html><head>
//  <title>Captive Portal Demo</title>
//  <meta name="viewport" content="width=device-width, initial-scale=1">
//  </head><body>
//  <h3>Captive Portal Demo</h3>
//  <br><br>
//  <form action="/get">
//    <br>
//    Name: <input type="text" name="name">
//    <br>
//    ESP32 Proficiency: 
//    <select name = "proficiency">
//      <option value=Beginner>Beginner</option>
//      <option value=Advanced>Advanced</option>
//      <option value=Pro>Pro</option>
//    </select>
//    <input type="submit" value="Submit">
//  </form>
//</body></html>)rawliteral";

class CaptiveRequestHandler : public AsyncWebHandler {
public:
  CaptiveRequestHandler() {}
  virtual ~CaptiveRequestHandler() {}

  bool canHandle(AsyncWebServerRequest *request){
    //request->addInterestingHeader("ANY");
    return true;
  }

  void handleRequest(AsyncWebServerRequest *request) {
    request->send(SD, "/index.html", "text/html"); 
  }
};

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

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SD, "/index.html", "text/html");
      Serial.println("Client Connected");
  });
 
  server.serveStatic("/", SD, "/");

  server.begin();

}


void setup(){
  //your other setup stuff.

  Serial.begin(115200);
  initSDCard();
  Serial.println();
  Serial.println("Setting up AP Mode");
  WiFi.mode(WIFI_AP); 
  WiFi.softAP("esp-captive");
  Serial.print("AP IP address: ");Serial.println(WiFi.softAPIP());
  Serial.println("Setting up Async WebServer");
  setupServer();
  Serial.println("Starting DNS Server");
  dnsServer.start(53, "*", WiFi.softAPIP());
  server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER);//only when requested from AP
  //more handlers...
  server.begin();
  Serial.println("All Done!");
}

void loop(){

}