import { writeFile } from 'node:fs/promises';
import { join, relative } from 'node:path';
import { buildCommandContext, } from '../../../app/command-context.js';
import { readGlobalOptions } from '../../shared/shared.utils.js';
import { readOatConfig, writeOatConfig } from '../../../config/oat-config.js';
import { resolveProjectRoot } from '../../../fs/paths.js';
import { Command, Option } from 'commander';
import { generateIndex, renderIndex } from './generator.js';
export const GENERATED_INDEX_WARNING = '<!-- AUTOGENERATED by `oat docs generate-index`. Do not hand-edit; changes are clobbered on every `predev` / `prebuild`. -->';
const DEFAULT_FILE_DEPS = {
    generateIndex,
    renderIndex,
    writeFile,
    readOatConfig,
    writeOatConfig,
    resolveRepoRoot: resolveProjectRoot,
};
const DEFAULT_DEPENDENCIES = {
    buildCommandContext,
    fileDeps: DEFAULT_FILE_DEPS,
};
function buildGeneratedIndexOutput(content) {
    if (!content) {
        return GENERATED_INDEX_WARNING;
    }
    return `${GENERATED_INDEX_WARNING}\n\n${content}`;
}
async function runIndexGenerate(context, options, deps) {
    const docsDir = join(context.cwd, options.docsDir);
    const outputPath = options.output
        ? join(context.cwd, options.output)
        : join(context.cwd, 'index.md');
    const entries = await deps.generateIndex(docsDir);
    const content = buildGeneratedIndexOutput(deps.renderIndex(entries));
    await deps.writeFile(outputPath, content, 'utf8');
    const repoRoot = await deps.resolveRepoRoot(context.cwd);
    const config = await deps.readOatConfig(repoRoot);
    const indexPath = relative(repoRoot, outputPath) || 'index.md';
    if (config.documentation?.index !== indexPath) {
        await deps.writeOatConfig(repoRoot, {
            ...config,
            documentation: {
                ...config.documentation,
                index: indexPath,
            },
        });
    }
    if (context.json) {
        context.logger.json({
            status: 'ok',
            entriesGenerated: entries.length,
            outputPath,
        });
        return;
    }
    context.logger.info(`Generated index with ${entries.length} entries → ${outputPath}`);
}
async function runIndexGenerateCommand(context, options, dependencies) {
    try {
        await runIndexGenerate(context, options, dependencies.fileDeps);
        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 createDocsGenerateIndexCommand(overrides = {}) {
    const dependencies = {
        ...DEFAULT_DEPENDENCIES,
        ...overrides,
    };
    return new Command('generate-index')
        .description('Generate a docs index from markdown files')
        .addOption(new Option('--docs-dir <path>', 'Documentation source directory').default('docs'))
        .addOption(new Option('--output <path>', 'Output file path (default: index.md)'))
        .action(async (options, command) => {
        const context = dependencies.buildCommandContext(readGlobalOptions(command));
        await runIndexGenerateCommand(context, options, dependencies);
    });
}
