/**
 * Mermaid diagram renderers for the architecture doc.
 *
 * Two diagrams: a directory mindmap so the user can see the *shape* of the
 * project at a glance, and a flowchart that shows which top-level module
 * imports from which. Both are small enough to fit in a single screenful so
 * they remain useful inside the LLM context window — large mermaid blobs
 * confuse smaller models, so we intentionally cap edges and nodes.
 */
import { DeepScanResult } from './scanner';

/**
 * Mindmap of the top-level directory layout. We render one branch per scanned
 * module and at most 6 sub-directories per module so the picture stays
 * scannable. Names that would otherwise collide with mermaid keywords are
 * defensively quoted.
 */
export function renderDirectoryTreeDiagram(scan: DeepScanResult): string {
    if (scan.topModules.length === 0) return '';
    const lines: string[] = ['```mermaid', 'mindmap', `  root((${_safeId(scan.projectName)}))`];
    for (const mod of scan.topModules) {
        lines.push(`    ${_safeId(mod.dir)}/`);
        for (const sub of mod.subDirs.slice(0, 6)) {
            lines.push(`      ${_safeId(sub.name)}/`);
        }
    }
    lines.push('```');
    return lines.join('\n');
}

/**
 * Module-level dependency flowchart. Edges are aggregated across all files in
 * each top-level module so the result reads as "src/agents → src/core" rather
 * than per-file noise. Edges are deduped and unidirectional.
 */
export function renderModuleDependencyDiagram(scan: DeepScanResult): string {
    if (scan.topModules.length === 0) return '';
    const lines: string[] = ['```mermaid', 'flowchart LR'];
    // Declare nodes first so layout is stable even when a module has no deps.
    for (const mod of scan.topModules) {
        lines.push(`    ${_id(mod.dir)}["${_label(mod.dir, mod.fileCount)}"]`);
    }
    // Emit edges. Skip self-edges (already implicit) and dedupe.
    const seen = new Set<string>();
    for (const mod of scan.topModules) {
        for (const dep of mod.dependsOn) {
            if (dep === mod.dir) continue;
            const key = `${mod.dir}>${dep}`;
            if (seen.has(key)) continue;
            seen.add(key);
            lines.push(`    ${_id(mod.dir)} --> ${_id(dep)}`);
        }
    }
    lines.push('```');
    return lines.join('\n');
}

function _id(dir: string): string {
    return dir.replace(/[^A-Za-z0-9_]/g, '_');
}

function _label(dir: string, fileCount: number): string {
    return `${dir}/<br/>${fileCount} files`;
}

function _safeId(s: string): string {
    // Strip characters mermaid mindmap can interpret as syntax.
    return s.replace(/[()[\]{}|]/g, '').replace(/\s+/g, '_').slice(0, 40);
}
