import { WebSocketServer } from "ws";
import http from "http";
import fs from "fs";
import path from "path";

// Parse command-line args for --asset-root <path>
let ASSET_ROOT = null;
for (let i = 2; i < process.argv.length; i++) {
  if (process.argv[i] === "--asset-root" && i + 1 < process.argv.length) {
    ASSET_ROOT = process.argv[i + 1];
    break;
  }
}
if (!ASSET_ROOT) {
  ASSET_ROOT = path.join(__dirname, "dist");
}
ASSET_ROOT = path.resolve(ASSET_ROOT);
console.log(`WebRadar relay server started (asset_root=${ASSET_ROOT})`);

const PORT = 22006;
const WS_PATH = "/ws";

const MIME = {
  ".html": "text/html; charset=utf-8",
  ".js": "application/javascript",
  ".mjs": "application/javascript",
  ".css": "text/css",
  ".json": "application/json",
  ".png": "image/png",
  ".jpg": "image/jpeg",
  ".jpeg": "image/jpeg",
  ".svg": "image/svg+xml",
  ".ico": "image/x-icon",
  ".webp": "image/webp",
  ".woff": "font/woff",
  ".woff2": "font/woff2",
  ".ttf": "font/ttf",
  ".webmanifest": "application/manifest+json",
};

function serveStatic(req, res) {
  let urlPath = req.url.split("?")[0];
  if (urlPath === "/") urlPath = "/index.html";

  const filePath = path.join(ASSET_ROOT, urlPath);

  // Prevent path traversal
  if (!filePath.startsWith(ASSET_ROOT)) {
    res.writeHead(403);
    res.end("Forbidden");
    return;
  }

  fs.readFile(filePath, function (err, data) {
    if (err) {
      // SPA fallback: serve index.html for unknown routes
      fs.readFile(path.join(ASSET_ROOT, "index.html"), function (e2, html) {
        if (e2) {
          console.error(`index.html not found in: ${ASSET_ROOT}`);
          res.writeHead(404);
          res.end("Not found");
          return;
        }
        res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
        res.end(html);
      });
      return;
    }
    const ext = path.extname(filePath).toLowerCase();
    const mime = MIME[ext] || "application/octet-stream";
    res.writeHead(200, { "Content-Type": mime });
    res.end(data);
  });
}

const server = http.createServer(function (req, res) {
  // POST /reload: broadcast reload command to all WS clients
  if (req.method === "POST" && req.url === "/reload") {
    const msg = JSON.stringify({ cmd: "reload" });
    let sent = 0;
    web_socket_server.clients.forEach(function (client) {
      if (client.readyState === 1) {
        client.send(msg);
        sent++;
      }
    });
    console.log(`/reload -> pushed to ${sent} client(s)`);
    res.writeHead(200, { "Content-Type": "text/plain" });
    res.end("ok");
    return;
  }
  if (req.method !== "GET" && req.method !== "HEAD") {
    res.writeHead(405);
    res.end();
    return;
  }
  serveStatic(req, res);
});

const web_socket_server = new WebSocketServer({
  server: server,
  path: WS_PATH
});

web_socket_server.on("connection", (web_socket, request) => {
  const client_address = request.socket.remoteAddress.replace("::ffff:", "");
  console.info(`${client_address} connected (clients: ${web_socket_server.clients.size})`);

  web_socket.on("message", (message) => {
    // Broadcast to all other connected clients
    web_socket_server.clients.forEach((client) => {
      if (client.readyState === 1) { // OPEN
        client.send(message);
      }
    });
  });

  web_socket.on("close", () => {
    console.info(`${client_address} disconnected`);
  });

  web_socket.on("error", (error) => {
    console.error(error);
  });
});

server.listen(PORT, "0.0.0.0", function () {
  console.log(`WebRadar UI -> http://localhost:${PORT}`);
  console.log(`WebRadar WS  -> ws://localhost:${PORT}${WS_PATH}`);
});

server.on("error", function (err) {
  console.error("Server error: " + err.message);
});
