import { createServer, type IncomingMessage, type ServerResponse } from "node:http";
import { loadConfig } from "./config.js";
import { startScheduler } from "./scheduler.js";
import {
  handleHealth,
  handleGetStatus,
  handleGetHosts,
  handleGetHost,
  handleGetServices,
  handleGetService,
  handleGetNetwork,
  handleGetSites,
  handleGetSite,
  handleGetAlerts,
  handleGetSummary,
} from "./routes.js";
import {
  handleGetRules,
  handleGetRule,
  handleCreateRule,
  handleUpdateRule,
  handleDeleteRule,
  handleGetHistory,
  handleTestFire,
} from "./routes/alerts.js";

const PORT = parseInt(process.env.STATUS_SERVICE_PORT || "8086", 10);

type Handler = (req: IncomingMessage, res: ServerResponse) => void | Promise<void>;

function matchRoute(method: string, url: string): Handler | null {
  const path = url.split("?")[0];

  if (method === "GET") {
    if (path === "/health") return handleHealth;
    if (path === "/status") return handleGetStatus;
    if (path === "/status/hosts") return handleGetHosts;
    if (path === "/status/services") return handleGetServices;
    if (path === "/status/network") return handleGetNetwork;
    if (path === "/status/sites") return handleGetSites;
    if (path === "/status/alerts") return handleGetAlerts;
    if (path === "/status/summary") return handleGetSummary;

    const hostMatch = path.match(/^\/status\/hosts\/([^/]+)$/);
    if (hostMatch) return (_req, res) => handleGetHost(_req, res, decodeURIComponent(hostMatch[1]));

    const svcMatch = path.match(/^\/status\/services\/([^/]+)$/);
    if (svcMatch) return (_req, res) => handleGetService(_req, res, decodeURIComponent(svcMatch[1]));

    const siteMatch = path.match(/^\/status\/sites\/([^/]+)$/);
    if (siteMatch) return (_req, res) => handleGetSite(_req, res, decodeURIComponent(siteMatch[1]));
  }

  if (method === "GET" && path === "/alerts/rules") return handleGetRules;
  if (method === "POST" && path === "/alerts/rules") return handleCreateRule;
  if (method === "GET" && path === "/alerts/history") return handleGetHistory;
  if (method === "POST" && path === "/alerts/test-fire") return handleTestFire;

  const ruleMatch = path.match(/^\/alerts\/rules\/([^/]+)$/);
  if (ruleMatch) {
    const id = decodeURIComponent(ruleMatch[1]);
    if (method === "GET")    return (_req, res) => handleGetRule(_req, res, id);
    if (method === "PUT")    return (req, res) => handleUpdateRule(req, res, id);
    if (method === "DELETE") return (_req, res) => handleDeleteRule(_req, res, id);
  }

  return null;
}

loadConfig();
startScheduler();

const server = createServer(async (req, res) => {
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
  res.setHeader("Access-Control-Allow-Headers", "Content-Type");

  if (req.method === "OPTIONS") { res.writeHead(204); res.end(); return; }

  const handler = matchRoute(req.method || "GET", req.url || "/");
  if (!handler) {
    res.writeHead(404, { "Content-Type": "application/json" });
    res.end(JSON.stringify({ error: "Not found" }));
    return;
  }

  try {
    await handler(req, res);
  } catch (e) {
    console.error("Unhandled error:", e);
    if (!res.headersSent) {
      res.writeHead(500, { "Content-Type": "application/json" });
      res.end(JSON.stringify({ error: "Internal server error" }));
    }
  }
});

server.listen(PORT, () => {
  console.log(`Status service listening on port ${PORT}`);
});
