"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createCompletionCommand = createCompletionCommand;
const errors_1 = require("../../../lib/errors");
const output_1 = require("../../../lib/output");
const completion_1 = require("../../../lib/completion");
async function createCompletionCommand() {
    const { Command } = await import("commander");
    const command = new Command("completion");
    command.description("Generate, install, uninstall, or resolve shell completions.");
    command
        .command("script")
        .description("Print a sourceable Day Shift completion script.")
        .requiredOption("--shell <shell>", "Target shell: bash, zsh, or fish.")
        .action((...actionArgs) => {
        const commandInstance = actionArgs.at(-1);
        const shell = requireSupportedShell(commandInstance.opts().shell);
        process.stdout.write(`${(0, completion_1.createCompletionScript)(shell)}\n`);
    });
    command
        .command("install")
        .description("Install or update a Day Shift-managed shell completion integration.")
        .requiredOption("--shell <shell>", "Target shell: bash, zsh, or fish.")
        .option("--dry-run", "Show intended completion integration changes without writing files.")
        .option("--force", "Allow replacing an unmanaged shell-native completion file.")
        .action((...actionArgs) => {
        const commandInstance = actionArgs.at(-1);
        const shell = requireSupportedShell(commandInstance.opts().shell);
        const format = requireOutputFormat(commandInstance);
        const plan = (0, completion_1.installCompletionIntegration)({
            shell,
            dryRun: commandInstance.opts().dryRun,
            force: commandInstance.opts().force
        });
        if (plan.action === "blocked") {
            throw (0, errors_1.createUsageError)(plan.reason, [
                `Target path: ${plan.targetPath}`,
                "No files were changed."
            ]);
        }
        (0, output_1.emitSuccess)({
            command: "completion install",
            format,
            text: renderCompletionInstallText(plan),
            data: plan
        });
    });
    command
        .command("uninstall")
        .description("Remove only the Day Shift-managed shell completion integration.")
        .requiredOption("--shell <shell>", "Target shell: bash, zsh, or fish.")
        .option("--dry-run", "Show intended removal without writing files.")
        .action((...actionArgs) => {
        const commandInstance = actionArgs.at(-1);
        const shell = requireSupportedShell(commandInstance.opts().shell);
        const format = requireOutputFormat(commandInstance);
        const plan = (0, completion_1.uninstallCompletionIntegration)({
            shell,
            dryRun: commandInstance.opts().dryRun
        });
        (0, output_1.emitSuccess)({
            command: "completion uninstall",
            format,
            text: renderCompletionUninstallText(plan),
            data: plan
        });
    });
    command
        .command("complete")
        .description("Resolve completion candidates for a shell line without executing the target command.")
        .requiredOption("--shell <shell>", "Target shell: bash, zsh, or fish.")
        .requiredOption("--line <line>", "Current command line.")
        .requiredOption("--cursor <offset>", "Cursor offset within the current command line.", parseCursor)
        .action((...actionArgs) => {
        const commandInstance = actionArgs.at(-1);
        const shell = requireSupportedShell(commandInstance.opts().shell);
        const result = (0, completion_1.resolveCompletionRequest)({
            shell,
            line: commandInstance.opts().line,
            cursor: commandInstance.opts().cursor
        });
        const text = (0, completion_1.formatCompletionCandidatesForShell)(shell, result.candidates);
        if (text.length > 0) {
            process.stdout.write(`${text}\n`);
        }
    });
    return command;
}
function requireSupportedShell(value) {
    if (typeof value === "string" && (0, completion_1.isSupportedCompletionShell)(value)) {
        return value;
    }
    throw (0, errors_1.createUsageError)(`Unsupported completion shell: ${String(value)}.`, [`Supported shells: ${completion_1.SUPPORTED_COMPLETION_SHELLS.join(", ")}`]);
}
function requireOutputFormat(commandInstance) {
    const requestedFormat = commandInstance.optsWithGlobals().format;
    const format = (0, output_1.resolveOutputFormat)(requestedFormat);
    if (format === null) {
        throw (0, errors_1.createUsageError)("Output format must be one of: text, json.", [`Received: ${String(requestedFormat)}`]);
    }
    return format;
}
function parseCursor(value) {
    const parsed = Number(value);
    if (!Number.isInteger(parsed) || parsed < 0) {
        throw (0, errors_1.createUsageError)("Completion cursor must be a non-negative integer.", [`Received: ${value}`, `Exit behavior: exits with usage code ${errors_1.RuntimeExitCode.USAGE} before completion resolution runs.`]);
    }
    return parsed;
}
function renderCompletionInstallText(plan) {
    return [
        (0, output_1.renderTerminalHeading)("Completion Install", "title"),
        (0, output_1.renderTerminalSection)({
            heading: "Summary",
            fields: [
                { label: "Shell", value: plan.shell },
                { label: "Action", value: plan.action },
                { label: "Changed", value: plan.changed },
                { label: "Target path", value: plan.targetPath },
                { label: "Reason", value: plan.reason }
            ]
        }),
        "",
        (0, output_1.renderTerminalSection)({
            heading: "Write Boundary",
            lines: [
                plan.dryRun
                    ? (0, output_1.renderTerminalBoundary)({ kind: "dry-run" })
                    : plan.changed
                        ? (0, output_1.renderTerminalBoundary)({
                            kind: "write-applied",
                            target: plan.targetPath,
                            targetLabel: "Completion target"
                        })
                        : (0, output_1.renderTerminalBoundary)({
                            kind: "mutating-no-op",
                            target: plan.targetPath,
                            targetLabel: "Completion target",
                            reason: plan.reason
                        })
            ]
        })
    ].join("\n");
}
function renderCompletionUninstallText(plan) {
    return [
        (0, output_1.renderTerminalHeading)("Completion Uninstall", "title"),
        (0, output_1.renderTerminalSection)({
            heading: "Summary",
            fields: [
                { label: "Shell", value: plan.shell },
                { label: "Action", value: plan.action },
                { label: "Changed", value: plan.changed },
                { label: "Target path", value: plan.targetPath },
                { label: "Reason", value: plan.reason }
            ]
        }),
        "",
        (0, output_1.renderTerminalSection)({
            heading: "Write Boundary",
            lines: [
                plan.dryRun
                    ? (0, output_1.renderTerminalBoundary)({ kind: "dry-run" })
                    : plan.changed
                        ? (0, output_1.renderTerminalBoundary)({
                            kind: "write-applied",
                            target: plan.targetPath,
                            targetLabel: "Completion target"
                        })
                        : (0, output_1.renderTerminalBoundary)({
                            kind: "mutating-no-op",
                            target: plan.targetPath,
                            targetLabel: "Completion target",
                            reason: plan.reason
                        })
            ]
        })
    ].join("\n");
}
