#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <WebSocketsServer.h>
#include "GameControllers.h"

// WiFi credentials
const char* ssid = "admin";
const char* password = "12345678";

// Game controller setup
GameControllers controllers;
const int LATCH_PIN = 0;    // D3 (GPIO0)
const int CLOCK_PIN = 4;    // D2 (GPIO4)
const int DATA_PIN_0 = 5;   // D1 (GPIO5)

// Web server and WebSocket
AsyncWebServer server(80);
WebSocketsServer webSocket(81);

// HTML page
const char htmlPage[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
  <title>Gamepad Tester</title>
  <style>
    body { font-family: Arial; text-align: center; background: #111; color: #0f0; }
    h1 { margin-top: 30px; }
    #output { font-size: 24px; margin-top: 20px; }
  </style>
</head>
<body>
  <h1>🎮 Gamepad Button Status</h1>
  <div id="output">Waiting for input...</div>
  <script>
    const output = document.getElementById("output");
    const socket = new WebSocket(`ws://${location.host}/ws`);
    socket.onmessage = function(event) { output.innerText = event.data; };
  </script>
</body>
</html>
)rawliteral";

void setup() {
  Serial.begin(115200);
  Serial.println("\n🔌 Initializing Gamepad Controller...");
  
  // Initialize game controller
  controllers.init(LATCH_PIN, CLOCK_PIN);
  controllers.setController(0, GameControllers::SNES, DATA_PIN_0);
  Serial.println("🎮 Controller initialized (SNES on GPIO5)");
  
  // Connect to WiFi
  WiFi.begin(ssid, password);
  Serial.print("📶 Connecting to WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\n✅ WiFi Connected! IP: " + WiFi.localIP().toString());

  // Start web server
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", htmlPage);
  });
  server.begin();
  Serial.println("🌐 Web server started on port 80");

  // Start WebSocket server
  webSocket.begin();
  webSocket.onEvent(webSocketEvent);
  Serial.println("🔗 WebSocket server started on port 81");
}

void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length) {
  switch(type) {
    case WStype_DISCONNECTED:
      Serial.printf("[%u] Disconnected!\n", num);
      break;
    case WStype_CONNECTED:
      {
        IPAddress ip = webSocket.remoteIP(num);
        Serial.printf("[%u] Connected from %d.%d.%d.%d\n", num, ip[0], ip[1], ip[2], ip[3]);
      }
      break;
    case WStype_TEXT:
      // Handle incoming messages if needed
      break;
  }
}

void loop() {
  webSocket.loop();
  controllers.poll();
  
  static unsigned long lastPrint = 0;
  if (millis() - lastPrint > 200) { // Print every 200ms
    lastPrint = millis();
    printControllerState();
    sendControllerState();
  }
}

void printControllerState() {
  static const char* buttonNames[] = {"B", "Y", "SELECT", "START", "UP", "DOWN", "LEFT", "RIGHT", "A", "X", "L", "R"};
  String state = "🎮 Buttons: ";
  
  for (int i = 0; i < 12; i++) {
    if (controllers.down(0, (GameControllers::Button)i)) {
      state += buttonNames[i];
      state += " ";
    }
  }
  
  if (state == "🎮 Buttons: ") {
    state = "🎮 No buttons pressed";
  }
  
  Serial.println(state);
}

void sendControllerState() {
  String message;
  for (int i = 0; i < 12; i++) {
    message += controllers.down(0, (GameControllers::Button)i) ? "1" : "0";
  }
  webSocket.broadcastTXT(message);
}