/**
 * `wrnexus generate <type> <name>` — scaffold a page, component, API route, or
 * schema from a template. Keeps new files consistent and gets users moving fast.
 *
 *   wrnexus generate page about
 *   wrnexus generate component user-card
 *   wrnexus generate api users/list
 *   wrnexus generate schema signup
 */

import { existsSync, mkdirSync, writeFileSync } from "node:fs";
import { dirname, join, resolve } from "node:path";

export type GenerateType = "page" | "component" | "api" | "schema";

const ALIASES: Record<string, GenerateType> = {
  page: "page",
  p: "page",
  component: "component",
  c: "component",
  api: "api",
  a: "api",
  schema: "schema",
  s: "schema",
};

export interface GeneratedFile {
  /** Path relative to the `app/` directory. */
  path: string;
  content: string;
}

function toPascalCase(name: string): string {
  return name
    .split(/[^A-Za-z0-9]+/)
    .filter(Boolean)
    .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
    .join("");
}

function baseName(name: string): string {
  const parts = name.split("/");
  return parts[parts.length - 1] ?? name;
}

/** Produce the file (relative path + content) for a generate request. */
export function scaffold(type: GenerateType, name: string): GeneratedFile {
  const clean = name.replace(/\.(wrn|ts)$/, "").replace(/^\/+|\/+$/g, "");
  const pascal = toPascalCase(baseName(clean));

  switch (type) {
    case "page":
      return {
        path: `pages/${clean}.wrn`,
        content: `page ${pascal} {
  layout = "public"

  seo {
    title = "${pascal}"
  }

  view {
    <h1>${pascal}</h1>
    <p>Edit app/pages/${clean}.wrn to build this page.</p>
  }
}
`,
      };
    case "component":
      return {
        path: `components/${clean}.wrn`,
        content: `component ${pascal} {
  props {
    label = "${pascal}"
  }

  view {
    <div class="wire-${baseName(clean)}">{label}</div>
  }
}
`,
      };
    case "api":
      return {
        path: `api/${clean}.ts`,
        content: `import type { Context } from "@wrnexus/core";

export async function GET(ctx: Context): Promise<Response> {
  return Response.json({ ok: true, route: ctx.url.pathname });
}
`,
      };
    case "schema":
      return {
        path: `schemas/${clean}.ts`,
        content: `import { v } from "@wrnexus/validation";

export default v.object({
  name: v.string().min(1, "Required"),
});
`,
      };
  }
}

/** Write a scaffolded file under `<appRoot>/app`, refusing to overwrite. */
export function runGenerate(
  appRoot: string,
  typeArg: string | undefined,
  name: string | undefined,
): void {
  const type = typeArg ? ALIASES[typeArg] : undefined;
  if (!type || !name) {
    console.error("Usage: wrnexus generate <page|component|layout|api|schema> <name>");
    process.exit(1);
  }

  const file = scaffold(type, name);
  const target = join(resolve(appRoot), "app", file.path);
  if (existsSync(target)) {
    console.error(`Refusing to overwrite existing file: app/${file.path}`);
    process.exit(1);
  }
  mkdirSync(dirname(target), { recursive: true });
  writeFileSync(target, file.content, "utf8");
  console.log(`✓ Created app/${file.path}`);
}
