import { readFile, writeFile } from 'node:fs/promises';
import { join, resolve } from 'node:path';
import { buildCommandContext, } from '../../../app/command-context.js';
import { readGlobalOptions } from '../../shared/shared.utils.js';
import { Command, Option } from 'commander';
import YAML from 'yaml';
import { buildDocsNavTree } from './contents.js';
const DEFAULT_DEPENDENCIES = {
    buildCommandContext,
    syncDocsNavigation,
};
function replaceTopLevelYamlSection(source, key, replacement) {
    const lines = source.split(/\r?\n/);
    const startIndex = lines.findIndex((line) => line.startsWith(`${key}:`));
    if (startIndex < 0) {
        return `${source.trimEnd()}\n\n${replacement.trimEnd()}\n`;
    }
    let endIndex = startIndex + 1;
    while (endIndex < lines.length) {
        const line = lines[endIndex] ?? '';
        if (line.length > 0 && /^\S/.test(line)) {
            break;
        }
        endIndex += 1;
    }
    return [
        ...lines.slice(0, startIndex),
        ...replacement.trimEnd().split('\n'),
        ...lines.slice(endIndex),
    ].join('\n');
}
export async function syncDocsNavigation(options) {
    const mkdocsPath = join(options.appRoot, 'mkdocs.yml');
    const docsRoot = join(options.appRoot, 'docs');
    const nav = await buildDocsNavTree({ docsRoot });
    const mkdocsSource = await readFile(mkdocsPath, 'utf8');
    const navSection = YAML.stringify({ nav }).trimEnd();
    const updatedMkdocsSource = replaceTopLevelYamlSection(mkdocsSource, 'nav', navSection);
    await writeFile(mkdocsPath, `${updatedMkdocsSource.trimEnd()}\n`, 'utf8');
    return {
        appRoot: options.appRoot,
        docsRoot,
        mkdocsPath,
        nav,
    };
}
async function runDocsNavSyncCommand(context, options, dependencies) {
    try {
        const targetDir = options.targetDir ?? '.';
        const result = await dependencies.syncDocsNavigation({
            appRoot: resolve(context.cwd, targetDir),
        });
        if (context.json) {
            context.logger.json({
                status: 'ok',
                appRoot: result.appRoot,
                docsRoot: result.docsRoot,
                mkdocsPath: result.mkdocsPath,
                nav: result.nav,
            });
        }
        else {
            context.logger.info(`Synced docs navigation in ${targetDir}`);
            context.logger.info(`  MkDocs config: ${result.mkdocsPath}`);
            context.logger.info(`  Docs root: ${result.docsRoot}`);
        }
        process.exitCode = 0;
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        if (context.json) {
            context.logger.json({ status: 'error', message });
        }
        else {
            context.logger.error(message);
        }
        process.exitCode = 1;
    }
}
export function createDocsNavSyncCommand(overrides = {}) {
    const dependencies = {
        ...DEFAULT_DEPENDENCIES,
        ...overrides,
    };
    return new Command('sync')
        .description('Regenerate docs navigation from index.md contents')
        .addOption(new Option('--target-dir <path>', 'Docs app directory containing mkdocs.yml'))
        .action(async (options, command) => {
        const context = dependencies.buildCommandContext(readGlobalOptions(command));
        await runDocsNavSyncCommand(context, options, dependencies);
    });
}
