import { readFile, readdir } from 'node:fs/promises';
import { join } from 'node:path';
import { parseFrontmatter } from './frontmatter-parser.js';
/**
 * Scan planu/specs/ filesystem for spec.md files and build minimal Spec objects
 * from frontmatter. This catches specs not tracked in the JSON store.
 */
async function scanFilesystemSpecs(projectPath) {
    const specsDir = join(projectPath, 'planu/specs');
    let entries;
    try {
        entries = await readdir(specsDir);
    }
    catch {
        return [];
    }
    const specFolders = entries.filter((e) => /^SPEC-\d+-.+$/.test(e));
    const results = [];
    await Promise.all(specFolders.map(async (folder) => {
        try {
            const specMdPath = join(specsDir, folder, 'spec.md');
            const content = await readFile(specMdPath, 'utf-8');
            const { metadata: m } = parseFrontmatter(content);
            if (!m.id || !m.title) {
                return;
            }
            const str = (v, fallback = '') => typeof v === 'string' ? v : typeof v === 'number' ? v.toString() : fallback;
            const num = (v, fallback) => typeof v === 'number' ? v : fallback;
            const arr = (v) => (Array.isArray(v) ? v : []);
            results.push({
                id: str(m.id),
                title: str(m.title),
                slug: str(m.slug, folder.replace(/^SPEC-\d+-/, '')),
                type: str(m.type, 'feature'),
                scope: str(m.scope, 'feature'),
                status: str(m.status, 'draft'),
                difficulty: num(m.difficulty, 3),
                risk: str(m.risk, 'medium'),
                projectId: '',
                createdAt: str(m.created ?? m.createdAt),
                updatedAt: str(m.updated ?? m.updatedAt),
                specPath: join(specsDir, folder, 'spec.md'),
                technicalPath: join(specsDir, folder, 'spec.md'),
                estimation: {
                    devHours: num(m.devHours, 8),
                    reviewHours: num(m.reviewHours, 2),
                    totalCostUsd: num(m.totalCostUsd, 500),
                },
                actuals: null,
                target: str(m.target, 'backend'),
                tags: arr(m.tags),
                dependencies: arr(m.dependencies),
                blockedBy: arr(m.blockedBy),
                gitBranch: '',
                impactAnalysis: null,
            });
        }
        catch {
            /* skip unreadable specs */
        }
    }));
    return results;
}
/**
 * Merge store specs with filesystem specs. Filesystem specs take priority
 * because their spec.md frontmatter is updated with each implementation,
 * while store data may be stale for specs created before the store existed.
 * Store-only specs (no filesystem match) are still included.
 */
function mergeSpecs(storeSpecs, fsSpecs) {
    const seen = new Set();
    const merged = [];
    // Filesystem specs first (they have accurate status from spec.md)
    for (const fs of fsSpecs) {
        seen.add(fs.id);
        merged.push(fs);
    }
    // Add store-only specs not found on filesystem
    for (const store of storeSpecs) {
        if (!seen.has(store.id)) {
            merged.push(store);
        }
    }
    return merged;
}
/**
 * Legacy compatibility entrypoint.
 *
 * SPEC-1017 makes `planu/index.html` and generated per-spec reports forbidden
 * project-tree artifacts. Keep this function for old call sites, but make it
 * a best-effort read-only refresh so callers stop reintroducing legacy files.
 */
export async function regenerateSpecSummaryHtml(projectPath, specs, _changedSpecIds) {
    try {
        const fsSpecs = await scanFilesystemSpecs(projectPath);
        void mergeSpecs(specs, fsSpecs);
    }
    catch {
        /* best-effort — never fail the caller */
    }
}
//# sourceMappingURL=spec-summary-html.js.map