import { existsSync, readdirSync } from 'node:fs';
import { join, relative, sep } from 'node:path';
const IGNORED_DIRS = new Set(['docs', 'logs', 'scripts']);
function catOrder(k) {
    if (k.startsWith('skills/'))
        return 0;
    if (k === 'commands')
        return 1;
    if (k.startsWith('agents'))
        return 2;
    return 3;
}
/** Recursively scan a directory for .md files (ignoring logs/, scripts/, docs/). Paths are relative to `baseDir`. */
export function scanMdFiles(dir, baseDir) {
    const results = [];
    if (!existsSync(dir))
        return results;
    const entries = readdirSync(dir, { withFileTypes: true });
    for (const entry of entries) {
        const fullPath = join(dir, entry.name);
        const rel = relative(baseDir, fullPath);
        const topDir = rel.split(sep)[0];
        if (IGNORED_DIRS.has(topDir))
            continue;
        if (entry.isDirectory()) {
            results.push(...scanMdFiles(fullPath, baseDir));
        }
        else if (entry.isFile() && entry.name.endsWith('.md')) {
            results.push(rel);
        }
    }
    return results;
}
/** Group scanned files by category. Sort order: skills → commands → agents. */
export function groupFiles(files) {
    const groupMap = new Map();
    for (const file of files) {
        const parts = file.split(sep);
        let groupKey;
        if (parts[0] === 'skills' && parts.length > 2) {
            groupKey = `${parts[0]}/${parts[1]}`;
        }
        else if (parts[0] === 'agents' &&
            parts.length > 2 &&
            parts[1] === 'assets') {
            groupKey = 'agents/assets';
        }
        else {
            groupKey = parts[0];
        }
        if (!groupMap.has(groupKey))
            groupMap.set(groupKey, []);
        groupMap.get(groupKey).push(parts.at(-1));
    }
    const sortedKeys = [...groupMap.keys()].sort((a, b) => {
        const diff = catOrder(a) - catOrder(b);
        return diff === 0 ? a.localeCompare(b) : diff;
    });
    return sortedKeys.map((key) => {
        const rawFiles = groupMap.get(key);
        const sorted = rawFiles.sort((a, b) => {
            if (a === 'SKILL.md')
                return -1;
            if (b === 'SKILL.md')
                return 1;
            return a.localeCompare(b);
        });
        return { files: [...new Set(sorted)], relativePath: key };
    });
}
/** Merge context + root skills; context wins on name conflict. */
export function mergeSkillDirs(contextSkillsDir, rootSkillsDir) {
    const contextFiles = scanMdFiles(contextSkillsDir, contextSkillsDir);
    const rootFiles = scanMdFiles(rootSkillsDir, rootSkillsDir);
    const contextGroups = groupFiles(contextFiles);
    const rootGroups = groupFiles(rootFiles);
    const contextPaths = new Set(contextGroups.map((g) => g.relativePath));
    const merged = [
        ...contextGroups,
        ...rootGroups.filter((g) => !contextPaths.has(g.relativePath)),
    ];
    return merged.sort((a, b) => {
        const diff = catOrder(a.relativePath) - catOrder(b.relativePath);
        return diff === 0 ? a.relativePath.localeCompare(b.relativePath) : diff;
    });
}
export function computeStats(groups) {
    let totalSkills = 0;
    let totalCommands = 0;
    let totalAgents = 0;
    let totalFiles = 0;
    for (const g of groups) {
        totalFiles += g.files.length;
        if (g.relativePath.startsWith('skills/'))
            totalSkills++;
        else if (g.relativePath === 'commands')
            totalCommands = g.files.length;
        else if (g.relativePath.startsWith('agents'))
            totalAgents++;
    }
    return { groups, totalAgents, totalCommands, totalFiles, totalSkills };
}
