import { readFileSync } from "node:fs";
import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
import { join } from "node:path";
import type { Server, ServerWebSocket } from "bun";
import { createHourlyJsonlWriter, logRetentionBytesForService } from "../../shared/src/rotating-jsonl";
import { notificationStyles } from "./notification-styles";

interface RuntimeConfig {
  port: number;
  coreInternalUrl: string;
  frontendPublicUrl: string;
  providerIngressPublicUrl: string;
  displayTime: DisplayTimeConfig;
  authUsername: string;
  authPassword: string;
  providerToken: string | null;
  sshClientToken: string | null;
  sshClientRouteAllowlist: string[];
  wechatArchiveToken: string | null;
  sessionSecret: string;
  sessionTtlSeconds: number;
  logFile: string;
  environment: RuntimeIdentity;
  deploy: {
    serviceId: string;
    repo: string;
    commit: string;
    requestedCommit: string;
  };
}

interface RuntimeIdentity {
  environment: string;
  namespace: string;
  databaseName: string;
  deployRef: string;
  serviceId: string;
  repo: string;
  commit: string;
  requestedCommit: string;
}

interface DisplayTimeConfig {
  timeZone: string;
  locale: string;
  label: string;
}

interface SessionPayload {
  username: string;
  expiresAt: number;
  nonce: string;
}

type JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue };

interface RequestPerformanceSample {
  at: string;
  component: string;
  method: string;
  path: string;
  status: number;
  durationMs: number;
  ok: boolean;
}

interface OperationPerformanceSample {
  at: string;
  service: string;
  operation: string;
  durationMs: number;
  ok: boolean;
  detail: string;
}

interface FrontendWsData {
  channel: "ssh-proxy";
  upstream: WebSocket | null;
  upstreamOpen: boolean;
  pendingToUpstream: string[];
  sshClient: {
    authenticatedBy: "session" | "client-token";
    routeAllowlist: string[];
    routeChecked: boolean;
  };
}

const sessionCookieName = "unidesk_session";
const config = readConfig();
const logger = createLogger("frontend", config.logFile);
const publicDir = join(import.meta.dir, "..", "public");
const vendorDir = join(import.meta.dir, "..", "node_modules");
const docsDir = join(import.meta.dir, "../../../..", "docs");
const appBundle = await buildFrontendApp("app.tsx");
const clientConfig = JSON.stringify({
  frontendPublicUrl: config.frontendPublicUrl,
  providerIngressPublicUrl: config.providerIngressPublicUrl,
  displayTime: config.displayTime,
  authUsername: config.authUsername,
  sessionTtlSeconds: config.sessionTtlSeconds,
  apiBaseUrl: "/api",
  environment: config.environment,
});
const indexHtmlTemplate = readFileSync(join(publicDir, "index.html"), "utf8");
const indexHtmlRootMarker = '<div id="root" data-config="__UNIDESK_CONFIG__"></div>';
const baiduNetdiskDocsFallbackLinks = [
  { href: "/docs/issue/baidu-netdisk-env-setup.md", section: "Baidu Netdisk hero action / 配置与文档 SETUP", label: "Baidu Netdisk 环境变量配置" },
  { href: "/docs/issue/baidu-netdisk-user-service.md", section: "配置与文档 DESIGN", label: "Baidu Netdisk 服务方案与 API" },
  { href: "/docs/reference/microservices.md", section: "配置与文档 REF", label: "UniDesk 用户服务安全边界" },
  { href: "/docs/reference/deployment.md", section: "配置与文档 DEPLOY", label: "UniDesk 部署与重建流程" },
  { href: "/docs/reference/cli.md", section: "配置与文档 CLI", label: "UniDesk CLI 验证命令" },
];
function renderIndexHtml(extraRootAttributes = ""): string {
  const docsFallback = `<nav hidden data-page="baidu-netdisk" data-section="配置与文档">${baiduNetdiskDocsFallbackLinks.map((link) => {
    const href = new URL(link.href, config.frontendPublicUrl).toString();
    return `<a href="${escapeHtmlAttribute(href)}" data-page-section="${escapeHtmlAttribute(link.section)}">${escapeHtmlText(link.label)}</a>`;
  }).join("")}</nav>`;
  const notificationStyleTag = `<style>${notificationStyles}</style>`;
  const htmlWithStyles = indexHtmlTemplate.includes("</head>")
    ? indexHtmlTemplate.replace("</head>", `${notificationStyleTag}</head>`)
    : indexHtmlTemplate;
  return htmlWithStyles.replace(
    indexHtmlRootMarker,
    `<div id="root" data-config="${escapeHtmlAttribute(clientConfig)}"${extraRootAttributes}>${docsFallback}</div>`,
  );
}

async function spaShellHtml(req: Request, pathname: string): Promise<string> {
  void req;
  void pathname;
  // Do not inline Codex task overview JSON into the root element: task prompts
  // can be very large and contain quote-heavy text, which makes malformed
  // markup failures show raw JSON at the page tail. The React page fetches the
  // same overview through the authenticated API after mounting.
  return renderIndexHtml();
}

const requestPerformanceSamples: RequestPerformanceSample[] = [];
const operationPerformanceSamples: OperationPerformanceSample[] = [];
const maxPerformanceSamples = 3000;

async function buildFrontendApp(entrypoint: string): Promise<string> {
  const result = await Bun.build({
    entrypoints: [join(import.meta.dir, entrypoint)],
    target: "browser",
    format: "iife",
    define: {
      "process.env.NODE_ENV": "\"production\"",
      "import.meta.env": "{\"MODE\":\"production\"}",
      "import.meta.env.MODE": "\"production\"",
    },
    minify: true,
    sourcemap: "none",
  });
  if (!result.success || result.outputs.length === 0) {
    const messages = result.logs.map((item) => item.message).join("; ");
    throw new Error(`frontend ${entrypoint} build failed: ${messages || "no output"}`);
  }
  return result.outputs[0].text();
}

function requiredEnv(name: string): string {
  const value = process.env[name];
  if (value === undefined || value.length === 0) {
    throw new Error(`Missing required environment variable: ${name}`);
  }
  return value;
}

function optionalEnv(name: string): string | null {
  const value = process.env[name]?.trim() ?? "";
  return value.length > 0 ? value : null;
}

function optionalFile(path: string): string | null {
  try {
    const value = readFileSync(path, "utf8").trim();
    return value.length > 0 ? value : null;
  } catch {
    return null;
  }
}

function optionalFileEnv(name: string, fallbackPath: string | null = null): string | null {
  const path = optionalEnv(name) ?? fallbackPath;
  return path === null ? null : optionalFile(path);
}

function requiredStringField(obj: Record<string, unknown>, key: string, path: string): string {
  const value = obj[key];
  if (typeof value !== "string" || value.trim().length === 0) throw new Error(`${path}.${key} must be a non-empty string`);
  return value.trim();
}

function recordField(obj: Record<string, unknown>, key: string, path: string): Record<string, unknown> {
  const value = obj[key];
  if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`${path}.${key} must be an object`);
  return value as Record<string, unknown>;
}

function validateTimeZone(value: string, path: string): void {
  try {
    new Intl.DateTimeFormat("en-US", { timeZone: value }).format(new Date(0));
  } catch {
    throw new Error(`${path} must be a valid IANA time zone`);
  }
}

function validateLocale(value: string, path: string): void {
  try {
    new Intl.DateTimeFormat(value).format(new Date(0));
  } catch {
    throw new Error(`${path} must be a valid Intl locale`);
  }
}

function readDisplayTimeConfig(): DisplayTimeConfig {
  const configPath = join(import.meta.dir, "../../../..", "config", "frontend.yaml");
  const parsed = Bun.YAML.parse(readFileSync(configPath, "utf8")) as unknown;
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) throw new Error("config/frontend.yaml must be an object");
  const root = parsed as Record<string, unknown>;
  if (root.kind !== "UniDeskFrontendConfig") throw new Error("config/frontend.yaml.kind must be UniDeskFrontendConfig");
  const displayTime = recordField(root, "displayTime", "config/frontend.yaml");
  const result = {
    timeZone: requiredStringField(displayTime, "timeZone", "config/frontend.yaml.displayTime"),
    locale: requiredStringField(displayTime, "locale", "config/frontend.yaml.displayTime"),
    label: requiredStringField(displayTime, "label", "config/frontend.yaml.displayTime"),
  };
  validateTimeZone(result.timeZone, "config/frontend.yaml.displayTime.timeZone");
  validateLocale(result.locale, "config/frontend.yaml.displayTime.locale");
  return result;
}

function readNumberEnv(name: string): number {
  const raw = requiredEnv(name);
  const parsed = Number(raw);
  if (!Number.isFinite(parsed) || parsed <= 0) {
    throw new Error(`Environment variable ${name} must be a positive number, got ${raw}`);
  }
  return parsed;
}

function deployEnv(name: "REF" | "SERVICE_ID" | "REPO" | "COMMIT" | "REQUESTED_COMMIT"): string {
  return process.env[`UNIDESK_FRONTEND_DEPLOY_${name}`]?.trim()
    || process.env[`UNIDESK_DEPLOY_${name}`]?.trim()
    || "";
}

function readConfig(): RuntimeConfig {
  const serviceId = deployEnv("SERVICE_ID") || "frontend";
  const repo = deployEnv("REPO");
  const commit = deployEnv("COMMIT");
  const requestedCommit = deployEnv("REQUESTED_COMMIT") || commit;
  return {
    port: readNumberEnv("PORT"),
    coreInternalUrl: requiredEnv("CORE_INTERNAL_URL"),
    frontendPublicUrl: requiredEnv("FRONTEND_PUBLIC_URL"),
    providerIngressPublicUrl: requiredEnv("PROVIDER_INGRESS_PUBLIC_URL"),
    displayTime: readDisplayTimeConfig(),
    authUsername: requiredEnv("AUTH_USERNAME"),
    authPassword: requiredEnv("AUTH_PASSWORD"),
    providerToken: optionalEnv("PROVIDER_TOKEN")
      ?? optionalEnv("UNIDESK_PROVIDER_TOKEN")
      ?? optionalFileEnv("PROVIDER_TOKEN_FILE", "/run/secrets/unidesk_provider_token")
      ?? optionalFileEnv("UNIDESK_PROVIDER_TOKEN_FILE", "/tmp/unidesk-provider-token"),
    sshClientToken: optionalEnv("UNIDESK_SSH_CLIENT_TOKEN")
      ?? optionalFileEnv("UNIDESK_SSH_CLIENT_TOKEN_FILE", "/run/secrets/unidesk_ssh_client_token"),
    sshClientRouteAllowlist: parseRouteAllowlist(optionalEnv("UNIDESK_SSH_CLIENT_ROUTE_ALLOWLIST") ?? "G14,G14:*,D601,D601:*"),
    wechatArchiveToken: optionalEnv("UNIDESK_WECHAT_ARCHIVE_TOKEN")
      ?? optionalFileEnv("UNIDESK_WECHAT_ARCHIVE_TOKEN_FILE", "/tmp/unidesk-wechat-archive-token"),
    sessionSecret: requiredEnv("SESSION_SECRET"),
    sessionTtlSeconds: readNumberEnv("SESSION_TTL_SECONDS"),
    logFile: requiredEnv("LOG_FILE"),
    environment: {
      environment: process.env.UNIDESK_ENV?.trim() || "prod",
      namespace: process.env.UNIDESK_NAMESPACE?.trim() || "",
      databaseName: process.env.UNIDESK_DATABASE_NAME?.trim() || process.env.UNIDESK_DEV_DATABASE_NAME?.trim() || "",
      deployRef: deployEnv("REF"),
      serviceId,
      repo,
      commit,
      requestedCommit,
    },
    deploy: {
      serviceId,
      repo,
      commit,
      requestedCommit,
    },
  };
}

function parseRouteAllowlist(raw: string): string[] {
  const items = raw.split(",").map((item) => item.trim()).filter((item) => item.length > 0);
  return items.length > 0 ? items : ["G14", "G14:*", "D601", "D601:*"];
}

function isDevIdentity(identity: RuntimeIdentity): boolean {
  return identity.environment === "dev" || identity.namespace === "unidesk-dev";
}

function frontendHealthPayload(): Record<string, unknown> {
  const base = { ok: true, service: "unidesk-frontend", frontendPublicUrl: config.frontendPublicUrl, deploy: config.deploy };
  if (!isDevIdentity(config.environment)) return base;
  return {
    ...base,
    environment: config.environment.environment,
    namespace: config.environment.namespace,
    databaseName: config.environment.databaseName,
    serviceId: config.deploy.serviceId,
    deployRef: config.environment.deployRef,
  };
}

function createLogger(service: string, logFile: string) {
  const writer = createHourlyJsonlWriter({
    baseLogFile: logFile,
    service,
    maxBytes: logRetentionBytesForService(service),
  });
  writer.prune();
  return (level: "debug" | "info" | "warn" | "error", message: string, data?: JsonValue): void => {
    const entry = data === undefined
      ? { ts: new Date().toISOString(), service, level, message }
      : { ts: new Date().toISOString(), service, level, message, data };
    const line = `${JSON.stringify(entry)}\n`;
    try {
      writer.appendLine(line, new Date(entry.ts));
    } catch (error) {
      console.error(JSON.stringify({ ts: new Date().toISOString(), service, level: "error", message: "log_write_failed", data: String(error) }));
    }
    const consoleMethod = level === "error" ? console.error : level === "warn" ? console.warn : console.log;
    consoleMethod(line.trimEnd());
  };
}

function contentType(pathname: string): string {
  if (pathname.endsWith(".html")) return "text/html; charset=utf-8";
  if (pathname.endsWith(".css")) return "text/css; charset=utf-8";
  if (pathname.endsWith(".js")) return "text/javascript; charset=utf-8";
  if (pathname.endsWith(".md")) return "text/markdown; charset=utf-8";
  if (pathname.endsWith(".svg")) return "image/svg+xml";
  if (pathname.endsWith(".ico")) return "image/x-icon";
  return "text/plain; charset=utf-8";
}

function textResponse(req: Request, body: string, type: string): Response {
  const headers = new Headers({ "content-type": type, "vary": "accept-encoding" });
  if (/\bgzip\b/u.test(req.headers.get("accept-encoding") ?? "")) {
    headers.set("content-encoding", "gzip");
    return new Response(Bun.gzipSync(body), { headers });
  }
  return new Response(body, { headers });
}

function jsonResponse(body: unknown, status = 200, extraHeaders?: HeadersInit): Response {
  const headers = new Headers({ "content-type": "application/json; charset=utf-8" });
  if (extraHeaders !== undefined) {
    new Headers(extraHeaders).forEach((value, key) => headers.set(key, value));
  }
  return new Response(JSON.stringify(body, null, 2), {
    status,
    headers,
  });
}

function safePreview(value: string, max = 400): string {
  const normalized = value.replace(/\s+/gu, " ").trim();
  return normalized.length > max ? `${normalized.slice(0, max)}...` : normalized;
}

function trimPerformanceBuffers(): void {
  while (requestPerformanceSamples.length > maxPerformanceSamples) requestPerformanceSamples.shift();
  while (operationPerformanceSamples.length > maxPerformanceSamples) operationPerformanceSamples.shift();
}

function classifyRequestComponent(pathname: string): string {
  if (pathname === "/api/frontend-performance") return "webui_performance";
  if (pathname === "/webhooks/wechat-archive") return "wechat_archive_webhook";
  if (pathname.startsWith("/api/") || pathname === "/logs") return "webui_api_proxy";
  if (pathname === "/login" || pathname === "/logout" || pathname === "/api/session") return "webui_auth";
  if (pathname === "/app.js" || pathname.startsWith("/vendor/") || /\/[^/]+\.[a-z0-9]+$/iu.test(pathname)) return "webui_static";
  return "webui_page";
}

function recordRequestPerformance(req: Request, pathname: string, response: Response | undefined, durationMs: number): void {
  const status = response?.status ?? 500;
  requestPerformanceSamples.push({
    at: new Date().toISOString(),
    component: classifyRequestComponent(pathname),
    method: req.method,
    path: pathname,
    status,
    durationMs,
    ok: status < 400,
  });
  trimPerformanceBuffers();
}

function recordOperationPerformance(service: string, operation: string, durationMs: number, ok: boolean, detail = "-"): void {
  operationPerformanceSamples.push({
    at: new Date().toISOString(),
    service,
    operation,
    durationMs,
    ok,
    detail: detail.length > 260 ? `${detail.slice(0, 257)}...` : detail,
  });
  trimPerformanceBuffers();
}

function percentile(values: number[], ratio: number): number {
  if (values.length === 0) return 0;
  const sorted = [...values].sort((left, right) => left - right);
  const index = Math.min(sorted.length - 1, Math.max(0, Math.ceil(sorted.length * ratio) - 1));
  return sorted[index] ?? 0;
}

function average(values: number[]): number {
  if (values.length === 0) return 0;
  return values.reduce((sum, value) => sum + value, 0) / values.length;
}

function roundMs(value: number): number {
  return Math.round(value * 10) / 10;
}

function summarizeRequestPerformance(): JsonValue[] {
  const groups = new Map<string, RequestPerformanceSample[]>();
  for (const sample of requestPerformanceSamples) {
    const rows = groups.get(sample.component) ?? [];
    rows.push(sample);
    groups.set(sample.component, rows);
  }
  return Array.from(groups.entries()).map(([component, rows]) => {
    const durations = rows.map((row) => row.durationMs);
    const failed = rows.filter((row) => !row.ok).length;
    return {
      component,
      requestCount: rows.length,
      failureCount: failed,
      failureRate: rows.length === 0 ? 0 : failed / rows.length,
      averageLatencyMs: roundMs(average(durations)),
      p95LatencyMs: roundMs(percentile(durations, 0.95)),
      maxLatencyMs: roundMs(Math.max(0, ...durations)),
    };
  }).sort((left, right) => Number((right as Record<string, JsonValue>).requestCount ?? 0) - Number((left as Record<string, JsonValue>).requestCount ?? 0)) as JsonValue[];
}

function summarizeOperationPerformance(): JsonValue[] {
  const groups = new Map<string, OperationPerformanceSample[]>();
  for (const sample of operationPerformanceSamples) {
    const key = `${sample.service}:${sample.operation}`;
    const rows = groups.get(key) ?? [];
    rows.push(sample);
    groups.set(key, rows);
  }
  return Array.from(groups.entries()).map(([key, rows]) => {
    const [service, ...operationParts] = key.split(":");
    const durations = rows.map((row) => row.durationMs);
    const failed = rows.filter((row) => !row.ok).length;
    return {
      service,
      operation: operationParts.join(":"),
      count: rows.length,
      failureCount: failed,
      averageLatencyMs: roundMs(average(durations)),
      p95LatencyMs: roundMs(percentile(durations, 0.95)),
      maxLatencyMs: roundMs(Math.max(0, ...durations)),
    };
  }).sort((left, right) => Number((right as Record<string, JsonValue>).count ?? 0) - Number((left as Record<string, JsonValue>).count ?? 0)) as JsonValue[];
}

function frontendPerformanceResponse(req: Request): Response {
  if (sessionFromRequest(req) === null) {
    return jsonResponse({ ok: false, error: "authentication required" }, 401);
  }
  const memory = process.memoryUsage();
  const recentOperationCutoff = Date.now() - 10 * 60 * 1000;
  return jsonResponse({
    ok: true,
    service: "frontend",
    generatedAt: new Date().toISOString(),
    appBundleBytes: Buffer.byteLength(appBundle, "utf8"),
    requests: {
      sampleCount: requestPerformanceSamples.length,
      componentSummary: summarizeRequestPerformance(),
      recentFailures: requestPerformanceSamples.filter((sample) => !sample.ok).slice(-20).reverse(),
    },
    operations: {
      sampleCount: operationPerformanceSamples.length,
      summary: summarizeOperationPerformance(),
      recentSlowOperations: operationPerformanceSamples
        .filter((sample) => {
          const at = Date.parse(sample.at);
          return Number.isFinite(at) && at >= recentOperationCutoff;
        })
        .sort((left, right) => Date.parse(right.at) - Date.parse(left.at))
        .slice(0, 20),
    },
    process: {
      rssBytes: memory.rss,
      heapUsedBytes: memory.heapUsed,
      heapTotalBytes: memory.heapTotal,
      externalBytes: memory.external,
      arrayBuffersBytes: memory.arrayBuffers,
    },
  });
}

function escapeHtmlAttribute(value: string): string {
  return value
    .replace(/&/g, "&amp;")
    .replace(/"/g, "&quot;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;");
}

function escapeHtmlText(value: string): string {
  return value
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;");
}

function docsSlug(value: string): string {
  const slug = String(value || "")
    .trim()
    .toLowerCase()
    .replace(/[`*_~[\]().:：,，/\\?#%]+/gu, "")
    .replace(/\s+/gu, "-")
    .replace(/-+/gu, "-")
    .replace(/^-+|-+$/gu, "");
  return slug || "section";
}

function isSafeDocLink(url: string): boolean {
  return /^https?:\/\//u.test(url) || url.startsWith("/docs/");
}

function linkifiedMarkdownInline(value: string): string {
  const pattern = /(`[^`]+`|\[[^\]]+\]\((?:https?:\/\/|\/docs\/)[^) \t]+\)|https?:\/\/[^\s<>)]+|\/docs\/[^\s<>)]+)/gu;
  let cursor = 0;
  let html = "";
  for (const match of value.matchAll(pattern)) {
    const token = match[0];
    const index = match.index ?? 0;
    html += escapeHtmlText(value.slice(cursor, index));
    cursor = index + token.length;
    if (token.startsWith("`") && token.endsWith("`")) {
      html += `<code>${escapeHtmlText(token.slice(1, -1))}</code>`;
      continue;
    }
    const markdownLink = token.match(/^\[([^\]]+)\]\((.+)\)$/u);
    if (markdownLink !== null) {
      const [, label, href] = markdownLink;
      html += isSafeDocLink(href)
        ? `<a href="${escapeHtmlAttribute(href)}" target="_blank" rel="noreferrer">${escapeHtmlText(label)}</a>`
        : escapeHtmlText(token);
      continue;
    }
    html += `<a href="${escapeHtmlAttribute(token)}" target="_blank" rel="noreferrer">${escapeHtmlText(token)}</a>`;
  }
  html += escapeHtmlText(value.slice(cursor));
  return html;
}

function renderMarkdownBody(markdown: string): string {
  const lines = markdown.split(/\r?\n/u);
  let html = "";
  let paragraph: string[] = [];
  let listKind: "ul" | "ol" | null = null;
  let inFence = false;

  function flushParagraph(): void {
    if (paragraph.length === 0) return;
    html += `<p>${linkifiedMarkdownInline(paragraph.join(" "))}</p>`;
    paragraph = [];
  }

  function closeList(): void {
    if (listKind === null) return;
    html += `</${listKind}>`;
    listKind = null;
  }

  function openList(kind: "ul" | "ol"): void {
    flushParagraph();
    if (listKind === kind) return;
    closeList();
    listKind = kind;
    html += `<${kind}>`;
  }

  for (const line of lines) {
    if (/^```/u.test(line.trim())) {
      flushParagraph();
      closeList();
      html += inFence ? "</code></pre>" : "<pre><code>";
      inFence = !inFence;
      continue;
    }
    if (inFence) {
      html += `${escapeHtmlText(line)}\n`;
      continue;
    }
    const heading = line.match(/^(#{1,6})\s+(.+)$/u);
    if (heading !== null) {
      flushParagraph();
      closeList();
      const level = Math.min(6, heading[1].length);
      const title = heading[2].trim();
      html += `<h${level} id="${escapeHtmlAttribute(docsSlug(title))}">${linkifiedMarkdownInline(title)}</h${level}>`;
      continue;
    }
    const unordered = line.match(/^\s*-\s+(.+)$/u);
    if (unordered !== null) {
      openList("ul");
      html += `<li>${linkifiedMarkdownInline(unordered[1])}</li>`;
      continue;
    }
    const ordered = line.match(/^\s*\d+\.\s+(.+)$/u);
    if (ordered !== null) {
      openList("ol");
      html += `<li>${linkifiedMarkdownInline(ordered[1])}</li>`;
      continue;
    }
    if (line.trim().length === 0) {
      flushParagraph();
      closeList();
      continue;
    }
    paragraph.push(line.trim());
  }
  flushParagraph();
  closeList();
  if (inFence) html += "</code></pre>";
  return html;
}

function renderDocsHtml(relativePath: string, markdown: string): string {
  const firstHeading = markdown.match(/^#\s+(.+)$/mu)?.[1]?.trim();
  const title = firstHeading || relativePath.split("/").pop() || "UniDesk Docs";
  const escapedTitle = escapeHtmlText(title);
  return `<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>${escapedTitle} - UniDesk Docs</title>
  <style>
    :root { color-scheme: dark; --bg:#0d141a; --panel:#131d26; --line:#2b3a45; --text:#d7e3e7; --muted:#81939f; --accent:#d7a13a; --accent2:#4eb7a8; }
    * { box-sizing: border-box; }
    body { margin:0; color:var(--text); background:radial-gradient(circle at top left, rgba(78,183,168,.12), transparent 30%), var(--bg); font:15px/1.66 "Aptos Narrow", "Noto Sans", sans-serif; }
    main { width:min(980px, calc(100vw - 28px)); margin:24px auto 56px; padding:22px; border:1px solid var(--line); background:linear-gradient(180deg, rgba(255,255,255,.04), rgba(255,255,255,.015)), var(--panel); box-shadow:0 18px 46px rgba(0,0,0,.32); }
    nav { display:flex; flex-wrap:wrap; gap:8px; margin-bottom:18px; }
    a { color:var(--accent2); text-decoration:none; border-bottom:1px solid rgba(78,183,168,.35); }
    a:hover { color:var(--accent); border-bottom-color:var(--accent); }
    nav a { padding:4px 8px; border:1px solid var(--line); background:rgba(12,18,24,.62); color:var(--text); }
    h1, h2, h3, h4, h5, h6 { line-height:1.25; letter-spacing:.03em; }
    h1 { margin:0 0 14px; font-size:28px; }
    h2 { margin-top:28px; padding-top:16px; border-top:1px solid var(--line); color:#f1d18b; }
    h3 { color:#a6ded5; }
    code { padding:1px 4px; border:1px solid rgba(255,255,255,.08); background:rgba(0,0,0,.28); border-radius:3px; font-family:"Cascadia Mono","IBM Plex Mono",monospace; font-size:.9em; }
    pre { overflow:auto; padding:14px; border:1px solid var(--line); background:#071016; }
    pre code { padding:0; border:0; background:transparent; }
    li { margin:5px 0; }
    .path { margin:0 0 16px; color:var(--muted); font-size:12px; }
  </style>
</head>
<body>
  <main>
    <nav>
      <a href="/app/baidu-netdisk/">返回 Baidu Netdisk</a>
      <a href="/docs/issue/baidu-netdisk-env-setup.md">环境变量配置</a>
      <a href="/docs/issue/baidu-netdisk-user-service.md">服务设计文档</a>
      <a href="/docs/reference/microservices.md">用户服务参考</a>
    </nav>
    <p class="path">${escapeHtmlText(relativePath)}</p>
    ${renderMarkdownBody(markdown)}
  </main>
</body>
</html>`;
}

function safeDocsRelativePath(pathname: string): string | null {
  const raw = pathname === "/docs" ? "" : pathname.slice("/docs/".length);
  let decoded = "";
  try {
    decoded = decodeURIComponent(raw);
  } catch {
    return null;
  }
  if (!decoded || decoded.includes("\0") || decoded.includes("\\") || decoded.startsWith("/") || decoded.split("/").includes("..")) return null;
  if (!decoded.endsWith(".md")) return null;
  return decoded;
}

async function docsResponse(req: Request, url: URL): Promise<Response> {
  if (req.method !== "GET" && req.method !== "HEAD") return jsonResponse({ ok: false, error: "method not allowed" }, 405);
  if (sessionFromRequest(req) === null) return textResponse(req, "authentication required", "text/plain; charset=utf-8");
  const relativePath = safeDocsRelativePath(url.pathname);
  if (relativePath === null) return jsonResponse({ ok: false, error: "invalid docs path", path: url.pathname }, 400);
  const file = Bun.file(join(docsDir, relativePath));
  if (!(await file.exists())) return jsonResponse({ ok: false, error: "doc not found", path: relativePath }, 404);
  if (req.method === "HEAD") return new Response(null, { headers: { "content-type": "text/html; charset=utf-8" } });
  return textResponse(req, renderDocsHtml(relativePath, await file.text()), "text/html; charset=utf-8");
}

function signPayload(payload: string): string {
  return createHmac("sha256", config.sessionSecret).update(payload).digest("base64url");
}

function safeEqual(a: string, b: string): boolean {
  const left = Buffer.from(a);
  const right = Buffer.from(b);
  return left.length === right.length && timingSafeEqual(left, right);
}

function createSession(username: string): { token: string; expiresAt: number } {
  const expiresAt = Date.now() + config.sessionTtlSeconds * 1000;
  const payload: SessionPayload = { username, expiresAt, nonce: randomBytes(12).toString("base64url") };
  const encoded = Buffer.from(JSON.stringify(payload), "utf8").toString("base64url");
  return { token: `${encoded}.${signPayload(encoded)}`, expiresAt };
}

function verifySession(token: string | undefined): SessionPayload | null {
  if (!token) return null;
  const [encoded, signature, extra] = token.split(".");
  if (!encoded || !signature || extra !== undefined) return null;
  if (!safeEqual(signPayload(encoded), signature)) return null;
  try {
    const payload = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8")) as Partial<SessionPayload>;
    if (payload.username !== config.authUsername || typeof payload.expiresAt !== "number" || payload.expiresAt <= Date.now()) return null;
    if (typeof payload.nonce !== "string") return null;
    return payload as SessionPayload;
  } catch {
    return null;
  }
}

function parseCookies(header: string | null): Record<string, string> {
  const cookies: Record<string, string> = {};
  if (!header) return cookies;
  for (const item of header.split(";")) {
    const index = item.indexOf("=");
    if (index === -1) continue;
    const key = item.slice(0, index).trim();
    const value = item.slice(index + 1).trim();
    try {
      cookies[key] = decodeURIComponent(value);
    } catch {
      cookies[key] = value;
    }
  }
  return cookies;
}

function sessionFromRequest(req: Request): SessionPayload | null {
  return verifySession(parseCookies(req.headers.get("cookie"))[sessionCookieName]);
}

function timingSafeStringEqual(left: string, right: string): boolean {
  const leftBytes = Buffer.from(left, "utf8");
  const rightBytes = Buffer.from(right, "utf8");
  if (leftBytes.length !== rightBytes.length) return false;
  return timingSafeEqual(leftBytes, rightBytes);
}

function bearerTokenFromRequest(req: Request): string | null {
  const header = req.headers.get("authorization") ?? "";
  const match = /^Bearer\s+(.+)$/iu.exec(header);
  return match === null ? null : match[1]?.trim() ?? null;
}

function sshClientAuthFromRequest(req: Request): FrontendWsData["sshClient"] | null {
  if (sessionFromRequest(req) !== null) {
    return { authenticatedBy: "session", routeAllowlist: ["*"], routeChecked: true };
  }
  const expected = config.sshClientToken;
  const supplied = bearerTokenFromRequest(req);
  if (expected !== null && supplied !== null && timingSafeStringEqual(supplied, expected)) {
    return { authenticatedBy: "client-token", routeAllowlist: config.sshClientRouteAllowlist, routeChecked: false };
  }
  return null;
}

function sshRouteAllowed(providerId: unknown, routeAllowlist: string[]): boolean {
  if (routeAllowlist.includes("*")) return true;
  const route = typeof providerId === "string" ? providerId : "";
  if (route.length === 0) return false;
  return routeAllowlist.some((pattern) => {
    if (pattern === route) return true;
    if (pattern.endsWith("*")) return route.startsWith(pattern.slice(0, -1));
    return false;
  });
}

function setSessionCookie(token: string): string {
  return `${sessionCookieName}=${encodeURIComponent(token)}; HttpOnly; SameSite=Lax; Path=/; Max-Age=${config.sessionTtlSeconds}`;
}

function clearSessionCookie(): string {
  return `${sessionCookieName}=; HttpOnly; SameSite=Lax; Path=/; Max-Age=0`;
}

async function readLoginBody(req: Request): Promise<{ username: string; password: string }> {
  const contentTypeHeader = req.headers.get("content-type") ?? "";
  if (contentTypeHeader.includes("application/x-www-form-urlencoded") || contentTypeHeader.includes("multipart/form-data")) {
    const form = await req.formData();
    return { username: String(form.get("username") ?? ""), password: String(form.get("password") ?? "") };
  }
  const body = (await req.json()) as { username?: unknown; password?: unknown };
  return {
    username: typeof body.username === "string" ? body.username : "",
    password: typeof body.password === "string" ? body.password : "",
  };
}

async function login(req: Request): Promise<Response> {
  try {
    const body = await readLoginBody(req);
    if (body.username !== config.authUsername || body.password !== config.authPassword) {
      logger("warn", "login_failed", { username: body.username });
      return jsonResponse({ ok: false, error: "invalid credentials" }, 401);
    }
    const session = createSession(body.username);
    logger("info", "login_succeeded", { username: body.username, expiresAt: new Date(session.expiresAt).toISOString() });
    return jsonResponse(
      { ok: true, user: { username: body.username }, expiresAt: new Date(session.expiresAt).toISOString() },
      200,
      { "set-cookie": setSessionCookie(session.token) },
    );
  } catch (error) {
    logger("error", "login_failed", { error: error instanceof Error ? error.message : String(error) });
    return jsonResponse({ ok: false, error: "invalid login request" }, 400);
  }
}

function logout(): Response {
  return jsonResponse({ ok: true }, 200, { "set-cookie": clearSessionCookie() });
}

function sessionResponse(req: Request): Response {
  const session = sessionFromRequest(req);
  if (session === null) return jsonResponse({ ok: true, authenticated: false });
  return jsonResponse({ ok: true, authenticated: true, user: { username: session.username }, expiresAt: new Date(session.expiresAt).toISOString() });
}

async function readJsonRecord(req: Request, maxBytes: number): Promise<Record<string, unknown>> {
  const bytes = await req.arrayBuffer();
  if (bytes.byteLength > maxBytes) throw new Error(`request body exceeds ${maxBytes} bytes`);
  const text = Buffer.from(bytes).toString("utf8");
  const parsed = JSON.parse(text) as unknown;
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) throw new Error("request body must be a JSON object");
  return parsed as Record<string, unknown>;
}

function recordFrom(value: unknown): Record<string, unknown> {
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : {};
}

function stringFrom(value: unknown): string {
  return typeof value === "string" ? value : value === undefined || value === null ? "" : String(value);
}

function wechatArchiveTokenFromRequest(req: Request): string | null {
  return bearerTokenFromRequest(req) ?? req.headers.get("x-unidesk-wechat-archive-token")?.trim() ?? null;
}

function isValidArchiveRemotePath(path: string): boolean {
  return path.startsWith("/UniDesk/WeChatArchive/")
    && !path.includes("\0")
    && !path.split("/").includes("..")
    && path.length <= 1024;
}

function archiveContentPayload(body: Record<string, unknown>): Record<string, unknown> {
  const message = recordFrom(body.message);
  const archive = recordFrom(body.archive);
  const media = recordFrom(message.media);
  const langbotData = recordFrom(body.data);
  const langbotMessage = recordFrom(langbotData.message);
  const langbotComponents = Array.isArray(langbotMessage.root) ? langbotMessage.root : [];
  const langbotPlain = langbotComponents
    .filter((item) => recordFrom(item).type === "Plain")
    .map((item) => stringFrom(recordFrom(item).text))
    .join("");
  const langbotImage = recordFrom(langbotComponents.find((item) => recordFrom(item).type === "Image"));
  const messageType = stringFrom(message.messageType || body.messageType || "text").toLowerCase();
  const remotePath = stringFrom(archive.remotePath);
  if (!isValidArchiveRemotePath(remotePath)) throw new Error("archive.remotePath is outside the WeChat archive root");
  const filename = stringFrom(archive.filename || remotePath.split("/").filter(Boolean).pop() || "wechat-archive.txt");
  if (messageType === "image") {
    const dataBase64 = stringFrom(media.dataBase64 || archive.dataBase64 || body.dataBase64 || langbotImage.base64);
    if (!dataBase64) throw new Error("image archive payload is missing media.dataBase64");
    return { dataBase64, filename, remotePath, maxBytes: 10 * 1024 * 1024 };
  }
  const text = stringFrom(message.text || body.text || body.message || body.content || langbotPlain);
  const payloadHash = new Bun.CryptoHasher("sha256").update(JSON.stringify(body)).digest("hex");
  const content = `${text}\n\n---\nsource=unidesk-wechat-archive\npayloadSha256=${payloadHash}\n`;
  return { content, filename, remotePath, maxBytes: 10 * 1024 * 1024 };
}

async function coreJson(path: string, init?: RequestInit): Promise<Record<string, unknown>> {
  const response = await fetch(new URL(path, config.coreInternalUrl), {
    ...init,
    headers: {
      "content-type": "application/json",
      ...(init?.headers instanceof Headers ? Object.fromEntries(init.headers.entries()) : init?.headers as Record<string, string> | undefined),
    },
  });
  const text = await response.text();
  let parsed: unknown = text;
  try {
    parsed = text.length > 0 ? JSON.parse(text) : null;
  } catch {
    parsed = text;
  }
  if (!response.ok) return { ok: false, status: response.status, body: parsed };
  return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)
    ? { ok: true, status: response.status, ...(parsed as Record<string, unknown>) }
    : { ok: true, status: response.status, body: parsed };
}

async function waitBaiduTransfer(jobId: string, timeoutMs: number): Promise<Record<string, unknown>> {
  const deadline = Date.now() + timeoutMs;
  let last: Record<string, unknown> = { ok: false, error: "not-polled" };
  while (Date.now() < deadline) {
    last = await coreJson(`/api/microservices/baidu-netdisk/proxy/api/transfers/${encodeURIComponent(jobId)}`);
    const job = recordFrom(last.job);
    const status = stringFrom(job.status || last.status);
    if (status === "succeeded") return { ok: true, job };
    if (status === "failed" || status === "canceled") return { ok: false, job };
    await Bun.sleep(1000);
  }
  return { ok: false, error: "baidu-transfer-timeout", last };
}

function baiduFsIdFromJob(job: Record<string, unknown>): string {
  const result = recordFrom(job.result);
  const baidu = recordFrom(result.baidu);
  return stringFrom(baidu.fs_id || baidu.fsId || job.fsId);
}

async function wechatArchiveWebhook(req: Request): Promise<Response> {
  if (req.method !== "POST") return jsonResponse({ ok: false, error: "method not allowed" }, 405);
  const expected = config.wechatArchiveToken;
  const supplied = wechatArchiveTokenFromRequest(req);
  if (expected === null || supplied === null || !timingSafeStringEqual(supplied, expected)) {
    return jsonResponse({ ok: false, error: "authentication required", valuesPrinted: false }, 401);
  }
  const started = performance.now();
  try {
    const body = await readJsonRecord(req, 2 * 1024 * 1024);
    const uploadBody = archiveContentPayload(body);
    const created = await coreJson("/api/microservices/baidu-netdisk/proxy/api/transfers/upload-content", {
      method: "POST",
      body: JSON.stringify(uploadBody),
    });
    if (created.ok !== true) {
      recordOperationPerformance("frontend", "wechat_archive_upload_create", performance.now() - started, false, stringFrom(created.status));
      return jsonResponse({ ok: false, error: "baidu upload create failed", upstream: created, valuesPrinted: false }, 502);
    }
    const job = recordFrom(created.job);
    const jobId = stringFrom(job.id);
    if (!jobId) throw new Error("baidu upload create did not return job id");
    const waited = await waitBaiduTransfer(jobId, 90_000);
    const waitedJob = recordFrom(waited.job);
    const fsId = baiduFsIdFromJob(waitedJob);
    const remotePath = stringFrom(uploadBody.remotePath);
    const ok = waited.ok === true && fsId.length > 0;
    recordOperationPerformance("frontend", "wechat_archive_upload", performance.now() - started, ok, `${jobId}:${remotePath}`);
    logger(ok ? "info" : "warn", "wechat_archive_upload_finished", { ok, jobId, remotePath, fsIdPresent: fsId.length > 0 });
    return jsonResponse({
      ok,
      skip_pipeline: ok,
      readOnly: true,
      archive: {
        remotePath,
        fsId,
        local: recordFrom(created.local),
        uploadJob: waitedJob,
        listed: null,
      },
      valuesPrinted: false,
    }, ok ? 200 : 502);
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    recordOperationPerformance("frontend", "wechat_archive_upload", performance.now() - started, false, message);
    logger("warn", "wechat_archive_upload_failed", { error: message });
    return jsonResponse({ ok: false, error: message, valuesPrinted: false }, 400);
  }
}

async function proxyApi(req: Request, url: URL): Promise<Response> {
  if (sessionFromRequest(req) === null) {
    return jsonResponse({ ok: false, error: "authentication required" }, 401);
  }
  const upstreamUrl = new URL(`${url.pathname}${url.search}`, config.coreInternalUrl);
  const headers = new Headers(req.headers);
  headers.delete("host");
  headers.delete("connection");
  headers.delete("content-length");
  headers.delete("cookie");
  const init: RequestInit = { method: req.method, headers, redirect: "manual", signal: req.signal };
  if (req.method !== "GET" && req.method !== "HEAD") {
    init.body = await req.arrayBuffer();
  }
  let upstream: Response;
  const started = performance.now();
  try {
    upstream = await fetch(upstreamUrl, init);
    recordOperationPerformance("frontend", "core_proxy", performance.now() - started, upstream.ok, `${req.method} ${url.pathname}`);
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    recordOperationPerformance("frontend", "core_proxy", performance.now() - started, false, message);
    logger("warn", "proxy_upstream_failed", { path: url.pathname, upstreamUrl: upstreamUrl.toString(), error: message });
    return jsonResponse({ ok: false, error: { message: "upstream proxy failed", detail: message } }, 502);
  }
  const responseHeaders = new Headers();
  const upstreamContentType = upstream.headers.get("content-type");
  if (upstreamContentType !== null) responseHeaders.set("content-type", upstreamContentType);
  if ((upstreamContentType ?? "").toLowerCase().includes("text/event-stream")) {
    responseHeaders.set("cache-control", upstream.headers.get("cache-control") || "no-store, no-transform");
    responseHeaders.set("connection", "keep-alive");
    const buffering = upstream.headers.get("x-accel-buffering");
    if (buffering !== null) responseHeaders.set("x-accel-buffering", buffering);
    return new Response(upstream.body, { status: upstream.status, headers: responseHeaders });
  }
  return new Response(await upstream.arrayBuffer(), { status: upstream.status, headers: responseHeaders });
}

function coreSshWebSocketUrl(): string {
  const url = new URL("/ws/ssh", config.coreInternalUrl);
  url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
  url.searchParams.set("token", config.providerToken ?? "");
  return url.toString();
}

function webSocketDataText(message: string | Buffer): string {
  return typeof message === "string" ? message : Buffer.from(message).toString("utf8");
}

function flushSshProxyPending(ws: ServerWebSocket<FrontendWsData>): void {
  const upstream = ws.data.upstream;
  if (upstream === null || !ws.data.upstreamOpen || upstream.readyState !== WebSocket.OPEN) return;
  while (ws.data.pendingToUpstream.length > 0) upstream.send(ws.data.pendingToUpstream.shift()!);
}

function handleSshProxyClientMessage(ws: ServerWebSocket<FrontendWsData>, text: string): void {
  if (!ws.data.sshClient.routeChecked) {
    let message: Record<string, unknown>;
    try {
      message = JSON.parse(text) as Record<string, unknown>;
    } catch {
      ws.send(JSON.stringify({ type: "ssh.error", message: "invalid ssh open payload" }));
      closeSshProxy(ws, 1008, "invalid ssh open payload");
      return;
    }
    if (message.type !== "ssh.open") {
      ws.send(JSON.stringify({ type: "ssh.error", message: "ssh client token requires ssh.open as first message" }));
      closeSshProxy(ws, 1008, "ssh open required");
      return;
    }
    if (!sshRouteAllowed(message.providerId, ws.data.sshClient.routeAllowlist)) {
      ws.send(JSON.stringify({ type: "ssh.error", failureKind: "route-not-allowed", message: "ssh route is not allowed for this client token", route: String(message.providerId ?? "") }));
      closeSshProxy(ws, 1008, "ssh route not allowed");
      return;
    }
    ws.data.sshClient.routeChecked = true;
  }
  ws.data.pendingToUpstream.push(text);
  flushSshProxyPending(ws);
}

function closeSshProxy(ws: ServerWebSocket<FrontendWsData>, code = 1000, reason = "ssh proxy closed"): void {
  if (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING) {
    ws.close(code, reason);
  }
}

function openSshProxyUpstream(ws: ServerWebSocket<FrontendWsData>): void {
  const upstream = new WebSocket(coreSshWebSocketUrl());
  ws.data.upstream = upstream;
  upstream.addEventListener("open", () => {
    ws.data.upstreamOpen = true;
    flushSshProxyPending(ws);
  });
  upstream.addEventListener("message", (event) => {
    if (ws.readyState === WebSocket.OPEN) ws.send(event.data as string | Buffer);
  });
  upstream.addEventListener("close", (event) => {
    closeSshProxy(ws, event.code || 1000, event.reason || "ssh upstream closed");
  });
  upstream.addEventListener("error", () => {
    if (ws.readyState === WebSocket.OPEN) {
      ws.send(JSON.stringify({ type: "ssh.error", message: "frontend ssh upstream websocket error" }));
    }
    closeSshProxy(ws, 1011, "ssh upstream websocket error");
  });
}

function proxySshWebSocket(req: Request, server: Server<FrontendWsData>): Response | undefined {
  const sshClient = sshClientAuthFromRequest(req);
  if (sshClient === null) {
    return jsonResponse({ ok: false, error: "authentication required" }, 401);
  }
  if (config.providerToken === null) {
    return jsonResponse({ ok: false, error: "frontend ssh proxy is missing provider token" }, 503);
  }
  const upgraded = server.upgrade(req, {
    data: {
      channel: "ssh-proxy",
      upstream: null,
      upstreamOpen: false,
      pendingToUpstream: [],
      sshClient,
    } satisfies FrontendWsData,
  });
  return upgraded ? undefined : jsonResponse({ ok: false, error: "websocket upgrade failed" }, 400);
}

function vendorPath(pathname: string): string | null {
  if (pathname === "/vendor/react.production.min.js") return join(vendorDir, "react", "umd", "react.production.min.js");
  if (pathname === "/vendor/react-dom.production.min.js") return join(vendorDir, "react-dom", "umd", "react-dom.production.min.js");
  if (pathname === "/vendor/xyflow.css") return join(vendorDir, "@xyflow", "react", "dist", "style.css");
  return null;
}

async function staticResponse(req: Request, pathname: string): Promise<Response> {
  if (pathname === "/app.js") {
    return textResponse(req, appBundle, "text/javascript; charset=utf-8");
  }
  const vendor = vendorPath(pathname);
  const filePath = vendor ?? join(publicDir, pathname.replace(/^\/+/, ""));
  const file = Bun.file(filePath);
  if (!(await file.exists())) {
    return jsonResponse({ ok: false, error: "not found", path: pathname }, 404);
  }
  return new Response(file, { headers: { "content-type": contentType(pathname) } });
}

function isStaticAssetPath(pathname: string): boolean {
  return /\/[^/]+\.[a-z0-9]+$/iu.test(pathname);
}

async function handleRequest(req: Request, server: Server<FrontendWsData>): Promise<Response | undefined> {
  const url = new URL(req.url);
  logger("debug", "request", { path: url.pathname });
  try {
    if (url.pathname === "/health") {
      return jsonResponse(frontendHealthPayload());
    }
    if (url.pathname === "/login" && req.method === "POST") return login(req);
    if (url.pathname === "/logout" && req.method === "POST") return logout();
    if (url.pathname === "/api/session") return sessionResponse(req);
    if (url.pathname === "/api/frontend-performance") return frontendPerformanceResponse(req);
    if (url.pathname === "/webhooks/wechat-archive") return wechatArchiveWebhook(req);
    if (url.pathname === "/ws/ssh") return proxySshWebSocket(req, server);
    if (url.pathname.startsWith("/api/") || url.pathname === "/logs") return proxyApi(req, url);
    if (url.pathname === "/docs" || url.pathname.startsWith("/docs/")) return docsResponse(req, url);
    if (url.pathname === "/" || url.pathname === "/index.html") {
      return textResponse(req, await spaShellHtml(req, url.pathname), "text/html; charset=utf-8");
    }
    const safePath = url.pathname.replace(/^\/+/, "");
    if (safePath.includes("..") || safePath.includes("\0")) {
      return jsonResponse({ ok: false, error: "invalid path" }, 400);
    }
    if (!isStaticAssetPath(url.pathname)) {
      return textResponse(req, await spaShellHtml(req, url.pathname), "text/html; charset=utf-8");
    }
    return staticResponse(req, url.pathname);
  } catch (error) {
    logger("error", "request_failed", { path: url.pathname, error: error instanceof Error ? error.message : String(error) });
    return jsonResponse({ ok: false, error: "request failed" }, 500);
  }
}

const server = Bun.serve<FrontendWsData>({
  port: config.port,
  hostname: "0.0.0.0",
  idleTimeout: 120,
  async fetch(req, server) {
    const started = performance.now();
    const url = new URL(req.url);
    let response: Response | undefined;
    try {
      response = await handleRequest(req, server);
      return response;
    } finally {
      recordRequestPerformance(req, url.pathname, response, performance.now() - started);
    }
  },
  websocket: {
    open(ws) {
      if (ws.data.channel === "ssh-proxy") openSshProxyUpstream(ws);
    },
    message(ws, message) {
      if (ws.data.channel !== "ssh-proxy") return;
      handleSshProxyClientMessage(ws, webSocketDataText(message));
    },
    close(ws) {
      if (ws.data.channel !== "ssh-proxy") return;
      try {
        ws.data.upstream?.close();
      } catch {
        // Closing an already-closed upstream socket is harmless.
      }
    },
  },
});

logger("info", "server_listening", {
  url: `http://0.0.0.0:${server.port}`,
  coreInternalUrl: config.coreInternalUrl,
  frontendPublicUrl: config.frontendPublicUrl,
  providerIngressPublicUrl: config.providerIngressPublicUrl,
  logFile: config.logFile,
});
