/**
 * Typed-routes codegen. From the scanned page routes, emit `app/routes.gen.ts`
 * with a `Routes` map (path → param types) and an `href()` builder — so links
 * are checked at compile time (unknown path or missing param = type error).
 */

import type { Route } from "./match.ts";

export function generateRoutesFile(pages: Route[]): string {
  const seen = new Set<string>();
  const entries: string[] = [];
  for (const page of [...pages].sort((a, b) => a.raw.localeCompare(b.raw))) {
    if (seen.has(page.raw)) continue;
    seen.add(page.raw);
    const type = page.paramNames.length
      ? `{ ${page.paramNames.map((n) => `${JSON.stringify(n)}: string`).join("; ")} }`
      : "Record<string, never>";
    entries.push(`  ${JSON.stringify(page.raw)}: ${type};`);
  }

  return `// AUTO-GENERATED by \`wrnexus dev\` — do not edit.
// Typed routes: a compile-time map of every page path to its [param] types,
// plus an href() builder that fills params and rejects unknown paths.

export interface Routes {
${entries.join("\n") || "  [path: string]: Record<string, string>;"}
}

export type RoutePath = keyof Routes;

export function href<P extends RoutePath>(
  path: P,
  ...args: Routes[P] extends Record<string, never> ? [] : [params: Routes[P]]
): string {
  const params = (args[0] ?? {}) as Record<string, string>;
  return String(path)
    .split("/")
    .map((seg) =>
      seg.startsWith("[") && seg.endsWith("]")
        ? encodeURIComponent(params[seg.slice(1, -1)] ?? "")
        : seg,
    )
    .join("/");
}
`;
}
