/**
 * seeds/render.mjs — seeds.json → SEEDS.md renderer (C12, AC7).
 *
 * Mirrors `roadmap/render.mjs` in spirit: pure string-producing function that
 * takes the already-loaded seeds file + a Map<scope, roadmap> + the raw
 * state.json for task counting. All I/O happens in the caller (commands/roadmap.mjs).
 *
 * Layout:
 *   # Seeds
 *   *{n} active · {m} other · Last updated: ISO*
 *
 *   ## <Seed title>                         ← H2 per active seed
 *   **Goal:** …
 *   **Status:** active · **Tasks:** 12 active / 25 completed
 *   *Notes: <notes_url>* (when present)
 *
 *   | Scope | Milestone | Phases (done / total) | Tasks |
 *   |…|
 *
 *   ## Dormant / completed / archived        ← single H2 footer
 *   - **seed-a** (dormant) — 3 milestones · 7 tasks
 *   - …
 *
 * The footer groups everything non-active into one bullet list so readers
 * skimming SEEDS.md don't page through finished initiatives. A seed with
 * zero milestones still renders — operators need to see empty seeds they've
 * just created so they can assign milestones.
 */
/**
 * Build the task count map (scope, milestone_id) → {active, completed}.
 * Walks state.json once and hashes per (scope, milestone_id) key so seed
 * rendering is O(milestones) not O(seeds × milestones × tasks).
 */
function buildTaskCountIndex(state) {
    const index = new Map(); // key=`${scope}\0${milestone_id}` → {active,completed}
    const bump = (scope, milestoneId, bucket) => {
        if (!milestoneId)
            return;
        const key = `${scope || 'project'}\u0000${milestoneId}`;
        let rec = index.get(key);
        if (!rec) {
            rec = { active: 0, completed: 0 };
            index.set(key, rec);
        }
        rec[bucket] += 1;
    };
    for (const t of Object.values(state?.active_tasks || {})) {
        if (!t)
            continue;
        bump(t.scope, t.milestone_id, 'active');
    }
    for (const t of state?.completed_tasks || []) {
        if (!t)
            continue;
        bump(t.scope, t.milestone_id, 'completed');
    }
    return index;
}
function tasksFor(index, scope, milestoneId) {
    return index.get(`${scope || 'project'}\u0000${milestoneId}`) || { active: 0, completed: 0 };
}
/**
 * Look up a milestone by (scope, milestone_id) across the preloaded roadmap map.
 * Returns the milestone object or null. Caller handles null (orphan ref).
 */
function resolveMilestone(roadmapsByScope, scope, milestoneId) {
    const rm = roadmapsByScope instanceof Map ? roadmapsByScope.get(scope) : roadmapsByScope?.[scope];
    if (!rm || !Array.isArray(rm.milestones))
        return null;
    return rm.milestones.find((m) => m.id === milestoneId) || null;
}
/**
 * Count phase done/total for a milestone row. "Done" = status completed or skipped.
 */
function milestonePhaseProgress(milestone) {
    const phases = milestone?.phases || [];
    const done = phases.filter((p) => p.status === 'completed' || p.status === 'skipped').length;
    return { done, total: phases.length };
}
/**
 * Escape a pipe so it renders literally in a GFM table cell.
 */
function esc(s) {
    return String(s ?? '').replace(/\|/g, '\\|');
}
/**
 * renderSeedsMd(seedsFile, roadmapsByScope, state) → markdown string.
 *
 * Renders the canonical SEEDS.md content. Pure — no I/O.
 *
 * @param seedsFile loaded seeds.json contents
 * @param roadmapsByScope Map<scope, roadmap> OR plain object keyed by scope
 * @param state loaded state.json contents (for task counts); null is fine
 */
export function renderSeedsMd(seedsFile, roadmapsByScope, state) {
    const seeds = (seedsFile?.seeds || []).slice();
    const active = seeds.filter((s) => (s.status || 'active') === 'active');
    const dormant = seeds.filter((s) => (s.status || 'active') !== 'active');
    const updatedAt = seedsFile?.updated_at || new Date().toISOString();
    const index = buildTaskCountIndex(state || {});
    const lines = [];
    lines.push('# Seeds', '');
    lines.push(`*${active.length} active · ${dormant.length} other · Last updated: ${updatedAt}*`, '');
    if (active.length === 0 && dormant.length === 0) {
        lines.push('_No seeds declared. Run `apt-tools seed create --id <id> --title <title>`._', '');
    }
    // Active seeds — full H2 section each.
    for (const seed of active) {
        const refs = seed.milestones || [];
        let seedActive = 0;
        let seedCompleted = 0;
        for (const ref of refs) {
            const c = tasksFor(index, ref.scope, ref.milestone_id);
            seedActive += c.active;
            seedCompleted += c.completed;
        }
        lines.push(`## ${seed.title || seed.id}`, '');
        if (seed.goal)
            lines.push(`**Goal:** ${seed.goal}`, '');
        lines.push(`**ID:** \`${seed.id}\` · **Status:** ${seed.status || 'active'}`, '');
        lines.push(`**Tasks:** ${seedActive} active / ${seedCompleted} completed`, '');
        if (seed.notes_url) {
            lines.push(`*Notes: ${seed.notes_url}*`, '');
        }
        if (refs.length === 0) {
            lines.push('_No milestones assigned yet. Run `apt-tools seed assign`._', '');
            continue;
        }
        lines.push('| Scope | Milestone | Phases (done / total) | Tasks |');
        lines.push('|-------|-----------|-----------------------|-------|');
        for (const ref of refs) {
            const ms = resolveMilestone(roadmapsByScope, ref.scope, ref.milestone_id);
            const title = ms?.title || ref.milestone_id;
            const { done, total } = milestonePhaseProgress(ms);
            const counts = tasksFor(index, ref.scope, ref.milestone_id);
            const phaseCell = ms ? `${done} / ${total}` : '_orphan ref_';
            lines.push(`| ${esc(ref.scope)} | **${esc(title)}** (\`${esc(ref.milestone_id)}\`) | ${phaseCell} | ${counts.active} / ${counts.completed} |`);
        }
        lines.push('');
    }
    // Dormant / completed / archived — compact footer.
    if (dormant.length > 0) {
        lines.push('## Dormant / completed / archived', '');
        for (const seed of dormant) {
            const refs = seed.milestones || [];
            let seedTasks = 0;
            for (const ref of refs) {
                const c = tasksFor(index, ref.scope, ref.milestone_id);
                seedTasks += c.active + c.completed;
            }
            const closed = seed.closed_at ? ` · closed ${seed.closed_at}` : '';
            lines.push(`- **${seed.title || seed.id}** \`${seed.id}\` (${seed.status})${closed} — ${refs.length} milestones · ${seedTasks} tasks`);
        }
        lines.push('');
    }
    lines.push('---', '', '*Auto-generated from `.aperant/roadmap/seeds.json` by apt-tools*', '');
    return lines.join('\n');
}
//# sourceMappingURL=render.mjs.map