import { createServer } from "../src/server.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import { getAuthorizedTokenPrefix, getUnauthorizedResponse } from "../src/http-auth.js";
import { publicBaseUrl } from "../src/oauth.js";
import type { LoadedSkill } from "../src/types.js";
import type { IncomingMessage, ServerResponse } from "node:http";

// Import pre-bundled skills (generated by scripts/bundle-skills.ts at build time)
import { createRequire } from "node:module";
const require = createRequire(import.meta.url);
const skillsData = require("../src/skills.json");

const skills = skillsData as unknown as LoadedSkill[];

export default async function handler(
  req: IncomingMessage & { body?: unknown },
  res: ServerResponse,
) {
  // CORS headers for cross-origin MCP clients
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
  res.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, mcp-session-id, mcp-protocol-version");
  res.setHeader("Access-Control-Expose-Headers", "mcp-session-id, WWW-Authenticate");

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

  const tokenPrefix = getAuthorizedTokenPrefix({
    url: req.url,
    authorization: req.headers.authorization,
  });

  if (!tokenPrefix) {
    const baseUrl = publicBaseUrl(req);
    const unauthorized = getUnauthorizedResponse(`${baseUrl}/mcp`, req.method, `${baseUrl}/.well-known/oauth-protected-resource/mcp`);
    for (const [key, value] of Object.entries(unauthorized.headers)) {
      res.setHeader(key, value);
    }
    res.writeHead(unauthorized.status);
    res.end(unauthorized.body);
    return;
  }

  res.setHeader("X-MCP-Access", "token");

  const server = createServer(skills);
  const transport = new StreamableHTTPServerTransport({
    sessionIdGenerator: undefined, // stateless
    enableJsonResponse: true,
  });

  await server.connect(transport);

  // Pass pre-parsed body if Vercel has already parsed it
  await transport.handleRequest(req, res, req.body);

  // Clean up when the response finishes
  res.on("close", () => {
    transport.close();
    server.close();
  });
}
