/**
 * Status Command
 *
 * Displays artifact completion status for a change.
 */
import ora from 'ora';
import chalk from 'chalk';
import { getChangeDir } from '../../core/planning-home.js';
import { resolveRootForCommand, toPlanningHome, toRootOutput, withStoreFlag, isStoreSelectedRoot, } from '../../core/root-selection.js';
import { loadChangeContext, formatChangeStatus, } from '../../core/artifact-graph/index.js';
import { validateChangeExists, validateSchemaExists, getAvailableChanges, getStatusIndicator, getStatusColor, } from './shared.js';
// -----------------------------------------------------------------------------
// Command Implementation
// -----------------------------------------------------------------------------
export async function statusCommand(options) {
    // The root resolves (and the store banner prints) before the spinner starts
    // so the two do not fight over stderr.
    const root = await resolveRootForCommand(options, { json: options.json });
    if (!root) {
        return;
    }
    const spinner = options.json ? undefined : ora('Loading change status...').start();
    try {
        const planningHome = toPlanningHome(root);
        const projectRoot = root.path;
        const rootOutput = toRootOutput(root);
        const newChangeHint = withStoreFlag(root, 'openspec new change <name>');
        // Handle no-changes case gracefully — status is informational,
        // so "no changes" is a valid state, not an error.
        if (!options.change) {
            const available = await getAvailableChanges(projectRoot, root.changesDir);
            if (available.length === 0) {
                spinner?.stop();
                if (options.json) {
                    console.log(JSON.stringify({ changes: [], message: 'No active changes.', root: rootOutput }, null, 2));
                    return;
                }
                console.log(`No active changes. Create one with: ${newChangeHint}`);
                return;
            }
            // Changes exist but --change not provided
            spinner?.stop();
            throw new Error(`Missing required option --change. Available changes:\n  ${available.join('\n  ')}`);
        }
        const changeName = await validateChangeExists(options.change, projectRoot, root.changesDir, { newChangeHint });
        // Validate schema if explicitly provided
        if (options.schema) {
            validateSchemaExists(options.schema, projectRoot);
        }
        // loadChangeContext will auto-detect schema from metadata if not provided
        const context = loadChangeContext(projectRoot, changeName, options.schema, {
            changeDir: getChangeDir(planningHome, changeName),
            planningHome,
        });
        const status = formatChangeStatus(context, isStoreSelectedRoot(root) ? { storeId: root.storeId } : {});
        spinner?.stop();
        if (options.json) {
            console.log(JSON.stringify({ ...status, root: rootOutput }, null, 2));
            return;
        }
        printStatusText(status);
    }
    catch (error) {
        spinner?.stop();
        throw error;
    }
}
export function printStatusText(status) {
    const doneCount = status.artifacts.filter((a) => a.status === 'done').length;
    const skippedCount = status.artifacts.filter((a) => a.status === 'skipped').length;
    const total = status.artifacts.length - skippedCount;
    console.log(`Change: ${status.changeName}`);
    console.log(`Schema: ${status.schemaName}`);
    if (status.changeRoot) {
        console.log(`Change root: ${status.changeRoot}`);
    }
    const skippedSuffix = skippedCount > 0 ? ` (${skippedCount} skipped)` : '';
    console.log(`Progress: ${doneCount}/${total} artifacts complete${skippedSuffix}`);
    console.log();
    for (const artifact of status.artifacts) {
        const indicator = getStatusIndicator(artifact.status);
        const color = getStatusColor(artifact.status);
        let line = `${indicator} ${artifact.id}`;
        if (artifact.status === 'skipped') {
            line += color(' (skipped: change declares skip_specs)');
        }
        if (artifact.status === 'blocked' && artifact.missingDeps && artifact.missingDeps.length > 0) {
            line += color(` (blocked by: ${artifact.missingDeps.join(', ')})`);
        }
        console.log(line);
    }
    if (status.isPlanningComplete) {
        console.log();
        console.log(chalk.green('All planning artifacts complete!'));
    }
}
//# sourceMappingURL=status.js.map