#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <map>
#include <array>

const char* ssid = "MIT";
const char* password = "K%PFa5@bB7";

const int redPin = 2;
const int greenPin = 3;
const int bluePin = 4;

std::map<String, std::array<int, 3>> colorMap = {
  {"off", {255, 255, 255}},
  {"red", {0, 255, 255}},
  {"green", {255, 0, 255}},
  {"blue", {255, 255, 0}},
  {"yellow", {0, 0, 255}},  
  {"cyan", {255, 0, 0}},    
  {"magenta", {0, 255, 0}},   
  {"white", {0, 0, 0}}        
};

AsyncWebServer server(80);

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

  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);

  analogWrite(redPin, 255);
  analogWrite(greenPin, 255);
  analogWrite(bluePin, 255);

  WiFi.begin(ssid, password);

  Serial.print("Connecting to WiFi");

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

  Serial.println("\nConnected to WiFi");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    String html = "<html><body>";
    html += "<p>Select a color:</p>";
    html += "<select onchange=\"setColor(this.value)\">";
    html += "<option value='off'>Off</option>";
    html += "<option value='red'>Red</option>";
    html += "<option value='green'>Green</option>";
    html += "<option value='blue'>Blue</option>";
    html += "<option value='yellow'>Yellow</option>";
    html += "<option value='cyan'>Cyan</option>";
    html += "<option value='magenta'>Magenta</option>";
    html += "<option value='white'>White</option>";
    html += "</select>";
    html += "<script>";
    html += "function setColor(color) {";
    html += "  var xhr = new XMLHttpRequest();";
    html += "  xhr.open('GET', '/setcolor?color=' + color, true);";
    html += "  xhr.send();";
    html += "}";
    html += "</script>";
    html += "</body></html>";
    request->send(200, "text/html", html);
  });

  server.on("/setcolor", HTTP_GET, [](AsyncWebServerRequest *request){
    String color = request->getParam("color")->value();
    setColor(color);
    request->send(200, "text/plain", "Color changed to " + color);
  });
  
  server.begin();
}

void loop() {
}

void setColor(String color) {
  if (colorMap.find(color) != colorMap.end()) {
    std::array<int, 3> rgb = colorMap[color];
    analogWrite(redPin, rgb[0]);
    analogWrite(greenPin, rgb[1]);
    analogWrite(bluePin, rgb[2]);
  }
}
