/**
 * Start Command
 *
 * Interactive one-shot onboarding for brand-new users. Designed to be the
 * landing experience for `npx @quickback-dev/cli start` in an empty folder.
 *
 * Difference from `create`:
 *  - No required args. Prompts for template (default: cloudflare) and project
 *    name (default: basename of cwd if cwd is empty, otherwise `my-app`).
 *  - Auto-detects an empty cwd and scaffolds in-place; otherwise creates a
 *    `./<name>/` subdirectory.
 *  - Lets the user keep going as long as possible before auth — the auth
 *    gate sits inside `runCreate`, just before the compile API call. If
 *    they cancel, the scaffold stays on disk and they're told how to
 *    finish later.
 *
 * `start` is the marketing entry point; `create` remains for scripting.
 */
import { readdirSync } from "fs";
import { basename, resolve } from "path";
import pc from "picocolors";
import prompts from "prompts";
import { getTemplate } from "../templates/registry.js";
import { runCreate } from "./create.js";
/**
 * Curated picker for first-time users. Aliases must exist in
 * TEMPLATE_ALIASES (validated at startup below) and `getTemplate(alias)`
 * must resolve to a `tier === 'free'` template — pro templates need a
 * subscription and we don't surface them in the logged-out onboarding flow.
 */
const START_TEMPLATES = [
    { alias: "cloudflare", label: "Cloudflare (bare scaffold) — Better Auth + D1 + Hono. Add your own features." },
    { alias: "todos", label: "Todos example — Working CRUD with masking + actions. Read the source." },
    { alias: "blog", label: "Blog / CMS — Single-tenant blog, public reads, admin writes." },
    { alias: "empty", label: "Empty scaffold — Config only, no features." },
];
/**
 * "Empty" for our purposes — ignore dotfiles and `.git`, since `git init`
 * is a perfectly reasonable thing to have done in the target folder.
 */
function isCwdEmptyEnough(cwd) {
    try {
        const entries = readdirSync(cwd).filter((name) => {
            if (name === '.git')
                return false;
            if (name.startsWith('.'))
                return false;
            return true;
        });
        return entries.length === 0;
    }
    catch {
        return false;
    }
}
function isValidProjectName(name) {
    if (!name || name.trim().length === 0)
        return "Name is required";
    if (!/^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$/.test(name)) {
        return "Use lowercase letters, numbers, and hyphens only";
    }
    return true;
}
export async function start(args) {
    if (args.includes("--help") || args.includes("-h")) {
        printHelp();
        return;
    }
    console.log(pc.bold("\nQuickback") + pc.gray(" · Welcome\n"));
    console.log(pc.gray("This will scaffold a Quickback project in the current"));
    console.log(pc.gray("directory. You don't need an account yet — we'll only"));
    console.log(pc.gray("ask for one just before compiling.\n"));
    const cwd = process.cwd();
    const cwdEmpty = isCwdEmptyEnough(cwd);
    // Curated free-tier picker. Validate each alias still resolves to a
    // free template — guards against the registry drifting from this list
    // (a Pro template sneaking in would block logged-out users at compile).
    const templateChoices = START_TEMPLATES.flatMap((t) => {
        const def = getTemplate(t.alias);
        if (!def || def.tier !== 'free')
            return [];
        const [name, description] = t.label.split(" — ");
        return [{
                title: name,
                description: description || def.description,
                value: t.alias,
            }];
    });
    const templateResponse = await prompts({
        type: "select",
        name: "template",
        message: "Choose a template",
        choices: templateChoices,
        initial: 0,
    });
    const template = templateResponse.template;
    if (!template) {
        console.log(pc.yellow("\nCancelled."));
        return;
    }
    // Project name default depends on whether cwd is empty. If the user is
    // running `npx quickback start` inside a freshly-created folder, use
    // that folder's name; otherwise suggest `my-app` and create a subdir.
    const defaultName = cwdEmpty ? basename(cwd) : "my-app";
    const nameResponse = await prompts({
        type: "text",
        name: "appName",
        message: cwdEmpty
            ? `Project name (will scaffold in current directory)`
            : `Project name (will create ./<name>/)`,
        initial: defaultName,
        validate: (v) => isValidProjectName(v),
    });
    const appName = nameResponse.appName;
    if (!appName) {
        console.log(pc.yellow("\nCancelled."));
        return;
    }
    // If cwd has content and the user picked a name matching cwd basename,
    // they probably wanted in-place — clarify with one confirm. Otherwise
    // default to subdir. This catches the common "I ran this in my project
    // folder by accident" case.
    const inPlace = cwdEmpty;
    if (!cwdEmpty && resolve(cwd, appName) === cwd) {
        console.error(pc.red("\nThis folder is not empty; refusing to scaffold in place."));
        console.log(pc.gray("Pick a different name (creates a subfolder) or run in an empty folder."));
        process.exit(1);
    }
    try {
        await runCreate({
            template,
            appName,
            inPlace,
        });
    }
    catch (error) {
        console.error(pc.red("\nProject creation failed:"));
        console.error(pc.red(String(error)));
        process.exit(1);
    }
}
function printHelp() {
    console.log(`
${pc.bold("quickback start")} - Interactive onboarding (recommended for new users)

${pc.bold("Usage:")}
  quickback start
  npx @quickback-dev/cli start

${pc.bold("What it does:")}
  • Prompts for a template and project name (no flags required)
  • Scaffolds in the current directory if empty, otherwise ./<name>/
  • Defers login until the compile step — cancel at the prompt and
    the scaffold stays on disk, ready for ${pc.cyan("quickback compile")} later

${pc.bold("Options:")}
  --help, -h   Show this help

${pc.bold("Scriptable alternative:")}
  ${pc.cyan("quickback create <template> <name>")}  ${pc.gray("— same flow, takes args")}
`);
}
//# sourceMappingURL=start.js.map