import { buildCommandContext, } from '../../../app/command-context.js';
import { readGlobalOptions } from '../../shared/shared.utils.js';
import { Command, Option } from 'commander';
import { scaffoldProject as defaultScaffoldProject, } from './scaffold.js';
const COMMIT_STATUS_MESSAGES = {
    skipped_disabled: 'Scaffold commit: skipped (--no-commit)',
    skipped_no_worktree: 'Scaffold commit: skipped (not a git work tree)',
    skipped_nothing: 'Scaffold commit: skipped (nothing to commit)',
};
const DEFAULT_DEPENDENCIES = {
    buildCommandContext,
    scaffoldProject: defaultScaffoldProject,
};
function reportSuccess(context, projectName, result) {
    if (context.json) {
        context.logger.json({
            status: 'ok',
            projectName,
            mode: result.mode,
            projectPath: result.projectPath,
            projectsRoot: result.projectsRoot,
            createdFiles: result.createdFiles,
            skippedFiles: result.skippedFiles,
            activePointerUpdated: result.activePointerUpdated,
            dashboardRefreshed: result.dashboardRefreshed,
            committed: result.committed,
            commitSha: result.commitSha,
            commitStatus: result.commitStatus,
            commitError: result.commitError,
        });
        return;
    }
    context.logger.info(`Created/updated OAT project: ${projectName}`);
    context.logger.info(`Project path: ${result.projectPath}`);
    if (result.activePointerUpdated) {
        context.logger.info('Active project updated in local config: .oat/config.local.json');
    }
    if (result.commitStatus === 'committed') {
        context.logger.info(`Scaffold commit: ${result.commitSha?.slice(0, 7) ?? 'committed'}`);
    }
    else if (result.commitStatus === 'failed') {
        // The scaffold itself succeeded, so this is a warning, not an error: do not
        // change the process exit code. Make clear the baseline was NOT committed.
        const detail = result.commitError ? `: ${result.commitError}` : '';
        context.logger.warn(`Warning: scaffold commit failed${detail}. The scaffolded files were written but NOT committed.`);
    }
    else {
        context.logger.info(COMMIT_STATUS_MESSAGES[result.commitStatus]);
    }
}
async function runProjectNew(projectName, options, context, dependencies) {
    try {
        const result = await dependencies.scaffoldProject({
            repoRoot: context.cwd,
            projectName,
            mode: options.mode,
            force: options.force,
            setActive: options.setActive,
            refreshDashboard: options.dashboard,
            commit: options.commit,
            projectLog: options.withProjectLog === true
                ? true
                : options.projectLog === false
                    ? false
                    : undefined,
        });
        reportSuccess(context, projectName, result);
        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 createProjectNewCommand(overrides = {}) {
    const dependencies = {
        ...DEFAULT_DEPENDENCIES,
        ...overrides,
    };
    return new Command('new')
        .description('Create or update an OAT project scaffold')
        .argument('<name>', 'Project name (letters, numbers, dash, underscore)')
        .addOption(new Option('--mode <mode>', 'Scaffold mode')
        .choices(['spec-driven', 'quick', 'import'])
        .default('spec-driven'))
        .option('--force', 'Non-destructive scaffold; create missing files only')
        .option('--no-set-active', 'Do not update active project in local config')
        .option('--no-dashboard', 'Do not refresh .oat/state.md after scaffold')
        .option('--no-commit', 'Do not git-commit the scaffolded project directory')
        .option('--with-project-log', 'Create project-log.md regardless of workflow.projectLog config')
        .option('--no-project-log', 'Do not create project-log.md during scaffolding')
        .action(async (name, options, command) => {
        if (name.startsWith('-')) {
            command.help();
            return;
        }
        const context = dependencies.buildCommandContext(readGlobalOptions(command));
        await runProjectNew(name, options, context, dependencies);
    });
}
