/**
 * commands/variant-gallery.mjs — `apt-tools variant-gallery <task-dir>` (C1, Wave 2).
 *
 * Scans <task-dir>/mockups/ for `iteration-NNN-variant-<letter>.html` files,
 * renders a gallery HTML that iframes each variant side-by-side, and writes
 * it as `iteration-NNN-gallery.html`.  The user opens the gallery via
 * `file://` and runs `/apt:mockup --pick <letter>` to promote one variant.
 *
 * Usage:
 *
 *   apt-tools variant-gallery <task-dir>                        # latest iteration
 *   apt-tools variant-gallery <task-dir> --iteration 001
 *   apt-tools variant-gallery <task-dir> --iteration 002 --feature "settings page"
 *   apt-tools variant-gallery <task-dir> --styles a=paper,b=bento,c=clean
 *
 * Output envelope (stdout):
 *
 *   {
 *     status: "ok",
 *     command: "variant-gallery",
 *     written: "<abs path to gallery html>",
 *     iteration: "001",
 *     variants: [{ letter, filename, style, description }, ...],
 *     skipped: [string, ...]          // files that didn't match the naming contract
 *   }
 *
 * Exit non-zero when the mockups directory has zero matching variants —
 * the skill is supposed to write them before calling this command, so an
 * empty pool is almost always an integration bug.
 */
import { existsSync, readdirSync, writeFileSync } from 'node:fs';
import { resolve as resolvePath } from 'node:path';
import { parseFlags } from '../util/args.mjs';
import { err, ok } from '../util/result.mjs';
import { renderGallery, variantEntriesFromFilenames } from '../variant/gallery.mjs';
/**
 * Scan the mockups dir for iteration-NNN-variant-X.html filenames and
 * return the highest NNN present.  Returns null when nothing matches.
 *
 * @param {string[]} filenames
 * @returns {string | null}
 */
function detectLatestIteration(filenames) {
    const re = /^iteration-(\d{3})-variant-[a-z]\.html$/i;
    const seen = new Set();
    for (const name of filenames) {
        const m = name.match(re);
        if (m)
            seen.add(m[1]);
    }
    if (seen.size === 0)
        return null;
    const sorted = [...seen].sort();
    return sorted[sorted.length - 1] ?? null;
}
/**
 * Parse `--styles a=paper,b=bento,c=clean` into a `{ a: { style: "paper" } }` record.
 * Unknown-format entries are silently skipped (the skill is allowed to pass
 * partial metadata).
 *
 * @param {string | undefined | true} raw
 * @returns {Record<string, { style?: string, description?: string }>}
 */
function parseStylesFlag(raw) {
    if (typeof raw !== 'string' || raw.length === 0)
        return {};
    const out = {};
    for (const pair of raw.split(',')) {
        const trimmed = pair.trim();
        if (!trimmed)
            continue;
        const eq = trimmed.indexOf('=');
        if (eq <= 0)
            continue;
        const letter = trimmed.slice(0, eq).trim().toLowerCase();
        const style = trimmed.slice(eq + 1).trim();
        if (!letter || !style)
            continue;
        out[letter] = { style };
    }
    return out;
}
export function cmdVariantGallery(taskDirArg, extraArgs) {
    if (!taskDirArg || typeof taskDirArg !== 'string' || taskDirArg.startsWith('--')) {
        return err('Usage: apt-tools variant-gallery <task-dir> [--iteration NNN] [--feature "<text>"] [--styles a=slug,b=slug,...]');
    }
    const flags = parseFlags(extraArgs ?? []);
    const iterationFlag = flags.get('iteration');
    const featureFlag = flags.get('feature');
    const stylesFlag = flags.get('styles');
    const taskDir = resolvePath(process.cwd(), taskDirArg);
    const mockupsDir = resolvePath(taskDir, 'mockups');
    if (!existsSync(mockupsDir)) {
        return err(`variant-gallery: mockups directory does not exist at ${mockupsDir}`);
    }
    let entries;
    try {
        entries = readdirSync(mockupsDir);
    }
    catch (e) {
        const msg = e instanceof Error ? e.message : String(e);
        return err(`variant-gallery: failed to read ${mockupsDir}: ${msg}`);
    }
    // Resolve iteration — explicit flag wins, else scan for latest.
    const iteration = typeof iterationFlag === 'string' && /^\d{1,3}$/.test(iterationFlag)
        ? iterationFlag.padStart(3, '0')
        : detectLatestIteration(entries);
    if (!iteration) {
        return err(`variant-gallery: no iteration-NNN-variant-X.html files found under ${mockupsDir}. Run \`/apt:mockup --variants N\` first.`);
    }
    // Filter to the chosen iteration's variant files.
    const iterationPrefix = `iteration-${iteration}-variant-`;
    const variantFilenames = entries
        .filter((n) => n.startsWith(iterationPrefix) && n.endsWith('.html'))
        .sort();
    const styleByLetter = parseStylesFlag(typeof stylesFlag === 'string' ? stylesFlag : undefined);
    const { variants, skipped } = variantEntriesFromFilenames(variantFilenames, styleByLetter);
    if (variants.length === 0) {
        return err(`variant-gallery: no variant files match iteration ${iteration}. Expected e.g. iteration-${iteration}-variant-a.html under ${mockupsDir}.`);
    }
    const feature = typeof featureFlag === 'string' && featureFlag.length > 0
        ? featureFlag
        : '(unspecified feature)';
    const html = renderGallery({
        feature,
        iteration,
        variants,
        taskDir,
    });
    const galleryPath = resolvePath(mockupsDir, `iteration-${iteration}-gallery.html`);
    try {
        writeFileSync(galleryPath, html, 'utf8');
    }
    catch (e) {
        const msg = e instanceof Error ? e.message : String(e);
        return err(`variant-gallery: failed to write ${galleryPath}: ${msg}`);
    }
    return ok({
        status: 'ok',
        command: 'variant-gallery',
        written: galleryPath,
        iteration,
        variants: variants.map((v) => ({
            letter: v.letter,
            filename: v.filename,
            style: v.style ?? null,
            description: v.description ?? null,
        })),
        skipped,
    });
}
//# sourceMappingURL=variant-gallery.mjs.map