/**
 * Output Utilities
 * Consistent output handling across all commands with --json, --quiet, --verbose support
 */
import chalk from 'chalk';
import ora from 'ora';
export class OutputManager {
    options;
    constructor(options = {}) {
        this.options = options;
    }
    /**
     * Print success message
     */
    success(message, data) {
        if (this.options.quiet)
            return;
        if (this.options.json && data) {
            this.json({ success: true, message, data });
        }
        else {
            console.log(chalk.green('✓'), message);
            if (data && this.options.verbose) {
                console.log(chalk.gray(JSON.stringify(data, null, 2)));
            }
        }
    }
    /**
     * Print error message
     */
    error(message, error, code) {
        if (this.options.json) {
            this.json({
                success: false,
                error: message,
                code: code || 'ERROR',
                details: error?.message || error,
                stack: this.options.verbose ? error?.stack : undefined,
            });
        }
        else {
            console.error(chalk.red('✗'), message);
            if (error && this.options.verbose) {
                console.error(chalk.gray(error.stack || error.message || error));
            }
        }
    }
    /**
     * Print warning message
     */
    warn(message, data) {
        if (this.options.quiet)
            return;
        if (this.options.json && data) {
            this.json({ warning: true, message, data });
        }
        else {
            console.log(chalk.yellow('⚠'), message);
            if (data && this.options.verbose) {
                console.log(chalk.gray(JSON.stringify(data, null, 2)));
            }
        }
    }
    /**
     * Print info message
     */
    info(message, data) {
        if (this.options.quiet)
            return;
        if (this.options.json && data) {
            this.json({ info: true, message, data });
        }
        else {
            console.log(chalk.cyan('ℹ'), message);
            if (data && this.options.verbose) {
                console.log(chalk.gray(JSON.stringify(data, null, 2)));
            }
        }
    }
    /**
     * Print debug message (only in verbose mode)
     */
    debug(message, data) {
        if (!this.options.verbose)
            return;
        console.log(chalk.gray('→'), chalk.gray(message));
        if (data) {
            console.log(chalk.gray(JSON.stringify(data, null, 2)));
        }
    }
    /**
     * Print JSON output
     */
    json(data) {
        console.log(JSON.stringify(data, null, 2));
    }
    /**
     * Print table (only in non-JSON, non-quiet mode)
     */
    table(data, headers) {
        if (this.options.quiet)
            return;
        if (this.options.json) {
            this.json(data);
        }
        else {
            // Use cli-table3 for formatted output
            const Table = require('cli-table3');
            if (headers) {
                const table = new Table({ head: headers });
                data.forEach(row => table.push(row));
                console.log(table.toString());
            }
            else {
                console.table(data);
            }
        }
    }
    /**
     * Print data (auto-detect format)
     */
    print(data) {
        if (this.options.quiet)
            return;
        if (this.options.json) {
            this.json(data);
        }
        else if (typeof data === 'string') {
            console.log(data);
        }
        else if (Array.isArray(data)) {
            this.table(data);
        }
        else if (typeof data === 'object') {
            console.log(JSON.stringify(data, null, 2));
        }
        else {
            console.log(data);
        }
    }
    /**
     * Create a spinner (only in non-JSON, non-quiet mode)
     */
    spinner(text) {
        if (this.options.quiet || this.options.json) {
            return {
                start: () => { },
                succeed: () => { },
                fail: () => { },
                warn: () => { },
                info: () => { },
                stop: () => { },
            };
        }
        return ora(text);
    }
    /**
     * Check if should show output
     */
    get shouldShow() {
        return !this.options.quiet;
    }
    /**
     * Check if JSON mode
     */
    get isJson() {
        return !!this.options.json;
    }
    /**
     * Check if verbose mode
     */
    get isVerbose() {
        return !!this.options.verbose;
    }
    /**
     * Check if quiet mode
     */
    get isQuiet() {
        return !!this.options.quiet;
    }
}
/**
 * Add global output options to a command
 */
export function addGlobalOptions(command) {
    return command
        .option('--json', 'Output as JSON')
        .option('--quiet', 'Suppress output')
        .option('--verbose', 'Show verbose output including debug info')
        .option('--options', 'Show available options for this command');
}
/**
 * Create output manager from command options
 */
export function createOutput(options) {
    return new OutputManager({
        json: options.json,
        quiet: options.quiet,
        verbose: options.verbose,
    });
}
/**
 * Error codes for consistent error handling
 */
export var ErrorCode;
(function (ErrorCode) {
    // General
    ErrorCode["UNKNOWN"] = "UNKNOWN";
    ErrorCode["INVALID_INPUT"] = "INVALID_INPUT";
    ErrorCode["OPERATION_FAILED"] = "OPERATION_FAILED";
    // Git
    ErrorCode["NOT_GIT_REPO"] = "NOT_GIT_REPO";
    ErrorCode["GIT_ERROR"] = "GIT_ERROR";
    // CV-Git
    ErrorCode["NOT_INITIALIZED"] = "NOT_INITIALIZED";
    ErrorCode["SYNC_REQUIRED"] = "SYNC_REQUIRED";
    ErrorCode["CONFIG_ERROR"] = "CONFIG_ERROR";
    // Services
    ErrorCode["SERVICE_UNAVAILABLE"] = "SERVICE_UNAVAILABLE";
    ErrorCode["FALKORDB_ERROR"] = "FALKORDB_ERROR";
    ErrorCode["QDRANT_ERROR"] = "QDRANT_ERROR";
    // Credentials
    ErrorCode["NO_CREDENTIALS"] = "NO_CREDENTIALS";
    ErrorCode["INVALID_CREDENTIALS"] = "INVALID_CREDENTIALS";
    ErrorCode["AUTH_FAILED"] = "AUTH_FAILED";
    // Platform
    ErrorCode["PLATFORM_ERROR"] = "PLATFORM_ERROR";
    ErrorCode["API_ERROR"] = "API_ERROR";
    ErrorCode["NETWORK_ERROR"] = "NETWORK_ERROR";
})(ErrorCode || (ErrorCode = {}));
/**
 * Create a consistent error with code
 */
export class CVError extends Error {
    code;
    details;
    constructor(message, code = ErrorCode.UNKNOWN, details) {
        super(message);
        this.code = code;
        this.details = details;
        this.name = 'CVError';
    }
}
/**
 * Handle error consistently
 */
export function handleError(error, output) {
    if (error instanceof CVError) {
        output.error(error.message, error, error.code);
    }
    else if (error instanceof Error) {
        output.error(error.message, error);
    }
    else {
        output.error('An unknown error occurred', error);
    }
    process.exit(1);
}
//# sourceMappingURL=output.js.map