"""Shell completion installer for bash, zsh, and fish."""

import os
import shutil
from pathlib import Path

import click

from mcpbundles.output import render_success, render_error, render_warning, stdout_console

_MARKER = "# mcpbundles shell completion"

_BASH_SCRIPT = """\
%(complete_func)s() {
    local IFS=$'\\n'
    COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \\
                   COMP_CWORD=$COMP_CWORD \\
                   _MCPBUNDLES_COMPLETE=bash_complete $1 ) )
    return 0
}

%(complete_func)ssetup() {
    complete -o default -F %(complete_func)s mcpbundles
}

%(complete_func)ssetup;
"""

_ZSH_SCRIPT = """\
#compdef mcpbundles

_mcpbundles() {
    local -a completions
    local -a completions_with_descriptions
    local -a response
    (( ! $+commands[mcpbundles] )) && return 1

    response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) _MCPBUNDLES_COMPLETE=zsh_complete mcpbundles)}")

    for key descr in ${(kv)response}; do
        if [[ "$descr" == "_" ]]; then
            completions+=("$key")
        else
            completions_with_descriptions+=("$key":"$descr")
        fi
    done

    if [ -n "$completions_with_descriptions" ]; then
        _describe -V unsorted completions_with_descriptions -U
    fi

    if [ -n "$completions" ]; then
        compadd -U -V unsorted -a completions
    fi
}

if [[ $zsh_eval_context[-1] == loadautofunc ]]; then
    _mcpbundles "$@"
else
    compdef _mcpbundles mcpbundles
fi
"""

_FISH_SCRIPT = """\
function __fish_mcpbundles_complete
    set -lx COMP_WORDS (commandline -cp)
    set -lx COMP_CWORD (math (count (commandline -opc)) - 1)
    set -lx _MCPBUNDLES_COMPLETE fish_complete
    set -l response (env _MCPBUNDLES_COMPLETE=fish_complete COMP_WORDS="$COMP_WORDS" COMP_CWORD=$COMP_CWORD mcpbundles)
    for completion in $response
        set -l metadata (string split "," -- $completion)
        if test (count $metadata) -eq 1
            echo $metadata[1]
        else
            echo -e $metadata[1]\\t$metadata[2]
        end
    end
end

complete -c mcpbundles -f -a "(__fish_mcpbundles_complete)"
"""

_SHELLS = {
    "bash": {
        "script": _BASH_SCRIPT % {"complete_func": "_mcpbundles_completion"},
        "rc_file": Path.home() / ".bashrc",
        "source_line": None,
    },
    "zsh": {
        "script": _ZSH_SCRIPT,
        "rc_file": Path.home() / ".zshrc",
        "source_line": None,
    },
    "fish": {
        "script": _FISH_SCRIPT,
        "rc_file": Path.home() / ".config" / "fish" / "completions" / "mcpbundles.fish",
        "source_line": None,
    },
}


@click.command("install-completion")
@click.argument("shell_name", type=click.Choice(["bash", "zsh", "fish"]))
def install_completion(shell_name: str) -> None:
    """Install shell tab completion for mcpbundles.

    Writes the completion script to your shell configuration. Restart your
    shell or source the config file to activate.

    Examples:
        mcpbundles install-completion bash
        mcpbundles install-completion zsh
        mcpbundles install-completion fish
    """
    shell_info = _SHELLS[shell_name]
    script = shell_info["script"]
    rc_file: Path = shell_info["rc_file"]

    if shell_name == "fish":
        rc_file.parent.mkdir(parents=True, exist_ok=True)
        rc_file.write_text(script)
        render_success(f"Wrote completion script to {rc_file}")
        stdout_console.print("  Completions will load automatically in new fish sessions.")
        return

    if rc_file.exists():
        existing = rc_file.read_text()
        if _MARKER in existing:
            render_warning(f"Completion already installed in {rc_file}")
            stdout_console.print(f"  Remove the '{_MARKER}' block from {rc_file} and re-run to reinstall.")
            return
    else:
        existing = ""

    completion_dir = Path.home() / ".mcpbundles" / "completions"
    completion_dir.mkdir(parents=True, exist_ok=True)
    script_file = completion_dir / f"mcpbundles.{shell_name}"
    script_file.write_text(script)
    script_file.chmod(0o644)

    with open(rc_file, "a") as f:
        f.write(f"\n{_MARKER}\n. {script_file}\n")

    render_success(f"Installed {shell_name} completion")
    stdout_console.print(f"  Script: [dim]{script_file}[/]")
    stdout_console.print(f"  Sourced from: [dim]{rc_file}[/]")
    stdout_console.print(f"  Run [cyan]source {rc_file}[/] or restart your shell to activate.")
