// engine/design-to-spec/spec-builder.ts — Assemble final spec.md markdown (SPEC-159)
import { generateAllAcs, getGlobalA11yRequirements } from './ac-generator.js';
import { buildUiContract, buildComponentTreeSummary, formatBreakpointsTable, } from './ui-contract-builder.js';
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
/** Format ACs as markdown checklist items */
function formatAcChecklist(acs) {
    return acs.map((ac) => `- [ ] ${ac}`).join('\n');
}
/** Collect all unique breakpoints across screens */
function collectUniqueBreakpoints(design) {
    const seen = new Set();
    const result = [];
    for (const screen of design.screens) {
        for (const bp of screen.breakpoints) {
            if (!seen.has(bp.name)) {
                seen.add(bp.name);
                result.push(bp);
            }
        }
    }
    return result;
}
// ---------------------------------------------------------------------------
// Section builders
// ---------------------------------------------------------------------------
function buildFrontmatter(design, projectId, platform) {
    const now = new Date().toISOString().split('T')[0];
    return [
        '---',
        `title: "${design.title}"`,
        `type: feature`,
        `scope: frontend`,
        `target: frontend`,
        `status: draft`,
        `platform: ${platform}`,
        `projectId: ${projectId}`,
        `created: ${now}`,
        `tags: [design, ui, ${platform}]`,
        '---',
    ].join('\n');
}
function buildScreenEntry(screen, allAcs) {
    const screenAcs = screen.acceptanceCriteria.length > 0
        ? screen.acceptanceCriteria
        : allAcs.filter((ac) => ac.startsWith(screen.name));
    return [
        `### Screen: ${screen.name}`,
        '',
        screen.description,
        '',
        '**Acceptance Criteria:**',
        '',
        formatAcChecklist(screenAcs.length > 0 ? screenAcs : [`${screen.name} renders correctly`]),
        '',
    ].join('\n');
}
function buildResponsiveSection(breakpoints) {
    if (breakpoints.length === 0) {
        return '';
    }
    return ['## Responsive Breakpoints', '', formatBreakpointsTable(breakpoints), ''].join('\n');
}
function buildA11ySection(includeA11y) {
    if (!includeA11y) {
        return '';
    }
    return [
        '## Accessibility Requirements (WCAG 2.1 AA)',
        '',
        ...getGlobalA11yRequirements().map((r) => `- [ ] ${r}`),
        '',
    ].join('\n');
}
// ---------------------------------------------------------------------------
// Public API
// ---------------------------------------------------------------------------
/**
 * Assembles a complete spec.md markdown string from a ParsedDesign.
 * Includes: YAML frontmatter, description, UI contract, ACs per screen, a11y section.
 */
export function buildSpecMarkdown(design, projectId, platform, includeA11y) {
    const allAcs = generateAllAcs(design.screens, platform, includeA11y);
    const uiContract = buildUiContract(design);
    const breakpoints = collectUniqueBreakpoints(design);
    return buildSpecMarkdownFromParts(design, projectId, platform, includeA11y, allAcs, breakpoints, uiContract);
}
/**
 * Internal assembly — accepts pre-computed values to avoid redundant computation
 * when called from assembleResult (which already has these values).
 */
function buildSpecMarkdownFromParts(design, projectId, platform, includeA11y, allAcs, breakpoints, uiContract) {
    const componentSummary = buildComponentTreeSummary(design.screens);
    const frontmatter = buildFrontmatter(design, projectId, platform);
    const descriptionSection = [
        `# ${design.title}`,
        '',
        '## Description',
        '',
        `Generated from design description. Platform: **${platform}**.`,
        '',
        '### Component Tree',
        '',
        componentSummary,
        '',
    ].join('\n');
    const screensSection = design.screens
        .map((s) => buildScreenEntry(s, allAcs))
        .join('\n');
    const acSection = ['## Acceptance Criteria', '', formatAcChecklist(allAcs), ''].join('\n');
    return [
        frontmatter,
        '',
        descriptionSection,
        '## Screens',
        '',
        screensSection,
        buildResponsiveSection(breakpoints),
        buildA11ySection(includeA11y),
        acSection,
        uiContract,
    ]
        .filter(Boolean)
        .join('\n');
}
/**
 * Assembles the full DesignToSpecResult from parsed design and config options.
 * Pre-computes shared values once to avoid redundant calls inside buildSpecMarkdown.
 */
export function assembleResult(design, projectId, platform, includeA11y) {
    // Pre-compute once — these are passed into buildSpecMarkdown to avoid re-computation
    const allAcs = generateAllAcs(design.screens, platform, includeA11y);
    const a11yReqs = includeA11y ? getGlobalA11yRequirements() : [];
    const breakpoints = collectUniqueBreakpoints(design);
    const uiContractMarkdown = buildUiContract(design);
    const specMarkdown = buildSpecMarkdownFromParts(design, projectId, platform, includeA11y, allAcs, breakpoints, uiContractMarkdown);
    return {
        specMarkdown,
        screens: design.screens,
        uiContractMarkdown,
        acceptanceCriteria: allAcs,
        a11yRequirements: a11yReqs,
        breakpoints,
        generatedAt: new Date().toISOString(),
    };
}
//# sourceMappingURL=spec-builder.js.map