import type { RuntimeMode } from "../shared/api";
import type { ProbeStore } from "./checker/store";
import type { RuntimeConfig } from "./config";
import type { Logger } from "./logger";
import type { StaticAssets } from "./static";

import { createApiError, jsonResponse } from "./helpers";
import { handleDashboard } from "./routes/dashboard";
import { handleHealth } from "./routes/health";
import { handleHistory } from "./routes/history";
import { handleMeta } from "./routes/meta";
import { handleMetrics } from "./routes/metrics";
import { serveStaticAsset } from "./static";

export interface StartServerOptions {
  config: RuntimeConfig;
  logger: Logger;
  mode: RuntimeMode;
  staticAssets?: StaticAssets;
  store: ProbeStore;
  version: string;
}

export function startServer(options: StartServerOptions) {
  const { config, logger, mode, staticAssets, store, version } = options;

  const server = Bun.serve({
    fetch(req) {
      if (staticAssets) {
        return serveStaticAsset(new URL(req.url).pathname, staticAssets);
      }
      return new Response("Frontend is served by Vite dev server on :5173", { status: 404 });
    },
    hostname: config.host,
    port: config.port,
    routes: {
      "/api/*": () => jsonResponse(createApiError("API route not found", 404), { mode, status: 404 }),
      "/api/dashboard": {
        GET: (req) => handleDashboard(new URL(req.url), store, mode),
      },
      "/api/meta": {
        GET: () => handleMeta(mode, version),
      },
      "/api/targets/:id/history": {
        GET: (req) => handleHistory(req.params.id, new URL(req.url), store, mode),
      },
      "/api/targets/:id/metrics": {
        GET: (req) => handleMetrics(req.params.id, new URL(req.url), store, mode),
      },
      "/health": {
        GET: () => handleHealth(mode),
      },
    },
  });

  logger.info({ host: config.host, port: config.port, url: server.url.toString() }, "DiAL listening");

  return server;
}
