/*
   Wall-E Rover Control
   ESP32-C3 + L298N (no PWM, full-speed only)
   - ESP32C3 creates its own WiFi network (AP mode)
   - User connects to SSID: "Wall-E Rover Control", password: "walle1234"
   - Visit http://192.168.4.1 in browser to control the rover

   By Jaagrav
*/

#include <WiFi.h>
#include <WebServer.h>

// ---------- Access Point Config ----------
const char* AP_SSID     = "Wall-E Rover Control";
const char* AP_PASSWORD = "walle1234";   // at least 8 chars

// ---------- L298N pins ----------
#ifndef D0
  // Define pin numbers for XIAO ESP32-C3 if D0..D4 aren’t mapped
  #define D0 2
  #define D1 3
  #define D3 5
  #define D4 4
#endif

const int IN1 = D0;  // Motor A
const int IN2 = D1;  // Motor A
const int IN3 = D3;  // Motor B
const int IN4 = D4;  // Motor B

WebServer server(80);

// ---------- Embedded Web UI ----------
const char INDEX_HTML[] PROGMEM = R"rawliteral(
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Wall-E Rover Control</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    body { font-family: Arial, sans-serif; display: grid; place-items: center; gap: 16px; margin: 20px; }
    .grid { display: grid; grid-template-columns: 100px 100px 100px; gap: 12px; }
    button {
      padding: 14px; border: none; border-radius: 12px;
      background: #4CAF50; color: white; font-weight: bold;
      box-shadow: 0 2px 6px rgba(0,0,0,0.2); cursor: pointer;
    }
    button:active { transform: scale(0.96); }
    h2 { margin-bottom: 0; }
  </style>
</head>
<body>
  <h2>Wall-E Rover Control</h2>
  <div class="grid">
    <span></span>
    <button onclick="go('forward')">↑ Forward</button>
    <span></span>

    <button onclick="go('left')">← Left</button>
    <button onclick="go('stop')">■ Stop</button>
    <button onclick="go('right')">Right →</button>

    <span></span>
    <button onclick="go('backward')">↓ Back</button>
    <span></span>
  </div>

<script>
function go(dir){
  fetch('/api/'+dir)
    .then(r=>r.json())
    .then(j=>console.log(j));
}
</script>
</body>
</html>
)rawliteral";

// ---------- Motor control ----------
void motorsStop() {
  digitalWrite(IN1, LOW); digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW); digitalWrite(IN4, LOW);
}

void motorsForward() {
  digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH); digitalWrite(IN4, LOW);
}

void motorsBackward() {
  digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH);
  digitalWrite(IN3, LOW); digitalWrite(IN4, HIGH);
}

void motorsLeft() {
  digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH);
  digitalWrite(IN3, HIGH); digitalWrite(IN4, LOW);
}

void motorsRight() {
  digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW); digitalWrite(IN4, HIGH);
}

// ---------- API helpers ----------
void sendJson(const char* state){
  server.send(200, "application/json", String("{\"state\":\"") + state + "\"}");
}

void handleForward(){ motorsForward(); sendJson("forward"); }
void handleBackward(){ motorsBackward(); sendJson("backward"); }
void handleLeft(){ motorsLeft(); sendJson("left"); }
void handleRight(){ motorsRight(); sendJson("right"); }
void handleStop(){ motorsStop(); sendJson("stopped"); }
void handleIndex(){ server.send(200, "text/html", INDEX_HTML); }

void setup() {
  // Motor pins
  pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT);
  motorsStop();

  Serial.begin(115200);
  delay(500);

  // Start Access Point
  WiFi.mode(WIFI_AP);
  WiFi.softAP(AP_SSID, AP_PASSWORD);
  Serial.println("Access Point started");
  Serial.print("SSID: "); Serial.println(AP_SSID);
  Serial.print("Password: "); Serial.println(AP_PASSWORD);
  Serial.print("Connect and open http://");
  Serial.println(WiFi.softAPIP());

  // Routes
  server.on("/", handleIndex);
  server.on("/api/forward", handleForward);
  server.on("/api/backward", handleBackward);
  server.on("/api/left", handleLeft);
  server.on("/api/right", handleRight);
  server.on("/api/stop", handleStop);

  server.begin();
  Serial.println("HTTP server ready.");
}

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