import { extname, normalize } from "node:path";
import { handleAgentDashboardRoute } from "./routes/agent-dashboard";
import { handleDashboardRoute } from "./routes/dashboard";

const host = process.env.HOST || "0.0.0.0";
const port = Number(process.env.PORT || 3000);
const distRoot = `${process.cwd()}/dist`;

const contentTypes = new Map([
  [".css", "text/css; charset=utf-8"],
  [".html", "text/html; charset=utf-8"],
  [".js", "text/javascript; charset=utf-8"],
  [".json", "application/json; charset=utf-8"],
  [".svg", "image/svg+xml"],
  [".wasm", "application/wasm"],
]);

export async function handleRequest(request: Request): Promise<Response> {
  const url = new URL(request.url);

  if (url.pathname === "/api/dashboard") {
    if (request.method !== "GET") return methodNotAllowed(["GET"]);
    return handleDashboardRoute();
  }

  if (url.pathname === "/api/agent/dashboard") {
    if (request.method !== "POST") return methodNotAllowed(["POST"]);
    return handleAgentDashboardRoute(request);
  }

  if (url.pathname.startsWith("/api/")) {
    return Response.json({ ok: false, message: "Not found" }, { status: 404 });
  }

  return serveStaticAsset(url.pathname);
}

async function serveStaticAsset(pathname: string): Promise<Response> {
  const safePath = normalize(pathname).replace(/^(\.\.(\/|\\|$))+/, "");
  const assetPath = safePath === "/" || safePath === "." ? "/index.html" : safePath;
  const file = Bun.file(`${distRoot}${assetPath}`);

  if (await file.exists()) {
    return new Response(file, {
      headers: contentTypeHeaders(assetPath),
    });
  }

  const fallback = Bun.file(`${distRoot}/index.html`);
  if (await fallback.exists()) {
    return new Response(fallback, {
      headers: contentTypeHeaders(".html"),
    });
  }

  return new Response("Build output not found", { status: 404 });
}

function methodNotAllowed(allowedMethods: string[]): Response {
  return Response.json(
    { ok: false, message: "Method not allowed" },
    {
      status: 405,
      headers: {
        Allow: allowedMethods.join(", "),
      },
    },
  );
}

function contentTypeHeaders(pathname: string): HeadersInit {
  const contentType = contentTypes.get(extname(pathname));
  return contentType ? { "Content-Type": contentType } : {};
}

if (import.meta.main) {
  Bun.serve({
    hostname: host,
    port,
    fetch: handleRequest,
  });

  console.info(`Dimension Lab website listening on http://${host}:${port}`);
}
