/**
 * completion command — generate shell completion scripts.
 *
 * Walks the Commander program tree to produce completions that are
 * always in sync with the actual CLI surface. Supports bash, zsh, and fish.
 *
 * Usage:
 *   ailf completion bash   # print bash completion script to stdout
 *   ailf completion zsh    # print zsh completion script to stdout
 *   ailf completion fish   # print fish completion script to stdout
 *
 * Install:
 *   ailf completion bash >> ~/.bashrc
 *   ailf completion zsh >> ~/.zshrc
 *   ailf completion fish > ~/.config/fish/completions/ailf.fish
 */
import { Command } from "commander";
export function createCompletionCommand(program) {
    return new Command("completion")
        .description("Generate shell completion scripts")
        .argument("<shell>", "Shell type: bash, zsh, or fish")
        .addHelpText("after", `
Examples:
  ailf completion bash               # print bash completions to stdout
  ailf completion zsh                # print zsh completions to stdout
  ailf completion fish               # print fish completions to stdout

  # Install permanently:
  ailf completion bash >> ~/.bashrc
  ailf completion zsh >> ~/.zshrc
  ailf completion fish > ~/.config/fish/completions/ailf.fish`)
        .action((shell) => {
        const commands = extractCommands(program);
        switch (shell) {
            case "bash":
                process.stdout.write(generateBash(commands));
                break;
            case "fish":
                process.stdout.write(generateFish(commands));
                break;
            case "zsh":
                process.stdout.write(generateZsh(commands));
                break;
            default:
                console.error(`Unknown shell: ${shell}. Supported: bash, zsh, fish`);
                process.exit(1);
        }
    });
}
// ---------------------------------------------------------------------------
// Bash completion
// ---------------------------------------------------------------------------
function escapeFish(s) {
    return s.replace(/'/g, "\\'");
}
// ---------------------------------------------------------------------------
// Zsh completion
// ---------------------------------------------------------------------------
function escapeZsh(s) {
    return s.replace(/'/g, "'\\''").replace(/\[/g, "\\[").replace(/]/g, "\\]");
}
function extractCommands(cmd) {
    return cmd.commands.map((sub) => ({
        description: sub.description(),
        name: sub.name(),
        options: sub.options.map((opt) => ({
            description: opt.description,
            flags: opt.long
                ? opt.short
                    ? [opt.short, opt.long]
                    : [opt.long]
                : opt.short
                    ? [opt.short]
                    : [],
        })),
        subcommands: extractCommands(sub),
    }));
}
// ---------------------------------------------------------------------------
// Fish completion
// ---------------------------------------------------------------------------
function generateBash(commands) {
    const topLevelNames = commands.map((c) => c.name).join(" ");
    // Build per-command option lists
    const cases = [];
    for (const cmd of commands) {
        const opts = cmd.options.flatMap((o) => o.flags).join(" ");
        if (cmd.subcommands.length > 0) {
            const subNames = cmd.subcommands.map((s) => s.name).join(" ");
            cases.push(`        ${cmd.name})
            COMPREPLY=( $(compgen -W "${subNames} ${opts}" -- "\${cur}") )
            return 0
            ;;`);
            for (const sub of cmd.subcommands) {
                const subOpts = sub.options.flatMap((o) => o.flags).join(" ");
                cases.push(`        ${sub.name})
            COMPREPLY=( $(compgen -W "${subOpts}" -- "\${cur}") )
            return 0
            ;;`);
            }
        }
        else {
            cases.push(`        ${cmd.name})
            COMPREPLY=( $(compgen -W "${opts}" -- "\${cur}") )
            return 0
            ;;`);
        }
    }
    return `# bash completion for ailf
# Generated by: ailf completion bash
# Install: ailf completion bash >> ~/.bashrc && source ~/.bashrc

_ailf_completions() {
    local cur prev commands
    COMPREPLY=()
    cur="\${COMP_WORDS[COMP_CWORD]}"
    prev="\${COMP_WORDS[COMP_CWORD-1]}"
    commands="${topLevelNames}"

    # Determine which command we're in
    local cmd=""
    local subcmd=""
    for ((i=1; i < COMP_CWORD; i++)); do
        case "\${COMP_WORDS[i]}" in
            -*)
                ;;
            *)
                if [ -z "$cmd" ]; then
                    cmd="\${COMP_WORDS[i]}"
                elif [ -z "$subcmd" ]; then
                    subcmd="\${COMP_WORDS[i]}"
                fi
                ;;
        esac
    done

    # Complete subcommand or command-specific options
    if [ -n "$subcmd" ]; then
        case "$subcmd" in
${cases.join("\n")}
        esac
    elif [ -n "$cmd" ]; then
        case "$cmd" in
${cases.join("\n")}
        esac
    else
        COMPREPLY=( $(compgen -W "\${commands}" -- "\${cur}") )
    fi

    return 0
}

complete -F _ailf_completions ailf
`;
}
function generateFish(commands) {
    const lines = [
        "# fish completion for ailf",
        "# Generated by: ailf completion fish",
        "# Install: ailf completion fish > ~/.config/fish/completions/ailf.fish",
        "",
        "# Disable file completions by default",
        "complete -c ailf -f",
        "",
        "# Top-level commands",
    ];
    for (const cmd of commands) {
        lines.push(`complete -c ailf -n '__fish_use_subcommand' -a '${cmd.name}' -d '${escapeFish(cmd.description)}'`);
    }
    lines.push("");
    for (const cmd of commands) {
        if (cmd.subcommands.length > 0) {
            lines.push(`# ${cmd.name} subcommands`);
            for (const sub of cmd.subcommands) {
                lines.push(`complete -c ailf -n '__fish_seen_subcommand_from ${cmd.name}' -a '${sub.name}' -d '${escapeFish(sub.description)}'`);
                for (const opt of sub.options) {
                    const long = opt.flags.find((f) => f.startsWith("--"));
                    if (long) {
                        const name = long.replace(/^--/, "");
                        lines.push(`complete -c ailf -n '__fish_seen_subcommand_from ${sub.name}' -l '${name}' -d '${escapeFish(opt.description)}'`);
                    }
                }
            }
        }
        else {
            lines.push(`# ${cmd.name} options`);
            for (const opt of cmd.options) {
                const long = opt.flags.find((f) => f.startsWith("--"));
                if (long) {
                    const name = long.replace(/^--/, "");
                    lines.push(`complete -c ailf -n '__fish_seen_subcommand_from ${cmd.name}' -l '${name}' -d '${escapeFish(opt.description)}'`);
                }
            }
        }
        lines.push("");
    }
    return lines.join("\n");
}
// ---------------------------------------------------------------------------
// Command factory
// ---------------------------------------------------------------------------
function generateZsh(commands) {
    const cmdEntries = commands
        .map((c) => `    '${c.name}:${escapeZsh(c.description)}'`)
        .join("\n");
    const subcases = [];
    for (const cmd of commands) {
        if (cmd.subcommands.length > 0) {
            const subEntries = cmd.subcommands
                .map((s) => `        '${s.name}:${escapeZsh(s.description)}'`)
                .join("\n");
            subcases.push(`    ${cmd.name})
      local -a subcmds
      subcmds=(
${subEntries}
      )
      _describe 'subcommand' subcmds
      ;;`);
        }
        else {
            const opts = cmd.options
                .map((o) => {
                const flag = o.flags[o.flags.length - 1]; // prefer long flag
                return `'${flag}[${escapeZsh(o.description)}]'`;
            })
                .join(" \\\n        ");
            subcases.push(`    ${cmd.name})
      _arguments \\
        ${opts || "'*:file:_files'"}
      ;;`);
        }
    }
    return `#compdef ailf
# zsh completion for ailf
# Generated by: ailf completion zsh
# Install: ailf completion zsh >> ~/.zshrc && source ~/.zshrc

_ailf() {
  local -a commands
  commands=(
${cmdEntries}
  )

  _arguments '1:command:->cmd' '*::arg:->args'

  case $state in
  cmd)
    _describe 'command' commands
    ;;
  args)
    case $words[1] in
${subcases.join("\n")}
    esac
    ;;
  esac
}

compdef _ailf ailf
`;
}
