"""Shell integration for Portal CLI with completions and functions."""

from __future__ import annotations

import os
import platform
from pathlib import Path
from typing import Any


class ShellIntegration:
    """Generate and manage shell integration scripts."""

    @staticmethod
    def get_bash_completion() -> str:
        """Get Bash completion script.

        Returns:
            Bash completion script content
        """
        return '''# Portal bash completion
_portal_completion() {
    local IFS=$'\\n'
    local response

    response=$(env COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD _PORTAL_COMPLETE=bash_complete $1)

    for completion in $response; do
        IFS=',' read type value <<< "$completion"

        if [[ $type == 'dir' ]]; then
            COMPREPLY=()
            compopt -o dirnames
        elif [[ $type == 'file' ]]; then
            COMPREPLY=()
            compopt -o default
        elif [[ $type == 'plain' ]]; then
            COMPREPLY+=($value)
        fi
    done

    return 0
}

complete -o nosort -F _portal_completion portal

# Portal cd function for automatic directory switching
portal_cd() {
    local result
    result=$(portal switch "$@" --print-path 2>/dev/null)
    local exit_code=$?

    if [ $exit_code -eq 0 ] && [ -n "$result" ]; then
        cd "$result" || return 1
        echo "Switched to: $result"
    else
        # If switch failed, still run the command to show error
        portal switch "$@"
    fi
}

# Alias for quick worktree switching
alias pw='portal_cd'

# Portal prompt integration (optional)
_portal_prompt_command() {
    # Add current worktree info to PS1 if in a worktree
    local worktree_info
    worktree_info=$(portal info --quiet 2>/dev/null)

    if [ $? -eq 0 ] && [ -n "$worktree_info" ]; then
        export PORTAL_WORKTREE_INFO="$worktree_info"
    else
        unset PORTAL_WORKTREE_INFO
    fi
}

# Uncomment to enable prompt integration
# PROMPT_COMMAND="_portal_prompt_command${PROMPT_COMMAND:+;$PROMPT_COMMAND}"'''

    @staticmethod
    def get_zsh_completion() -> str:
        """Get Zsh completion script.

        Returns:
            Zsh completion script content
        """
        return """# Portal zsh completion
_portal_completion() {
    local -a completions
    local -a completions_with_descriptions
    local -a response
    (( ! $+commands[portal] )) && return 1

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

    for type key descr in ${response}; do
        if [[ "$type" == "plain" ]]; then
            if [[ "$descr" == "_" ]]; then
                completions+=("$key")
            else
                completions_with_descriptions+=("$key":"$descr")
            fi
        elif [[ "$type" == "dir" ]]; then
            _path_files -/
        elif [[ "$type" == "file" ]]; then
            _path_files -f
        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
}

compdef _portal_completion portal

# Portal cd function for automatic directory switching
portal_cd() {
    local result
    result=$(portal switch "$@" --print-path 2>/dev/null)
    local exit_code=$?

    if [ $exit_code -eq 0 ] && [ -n "$result" ]; then
        cd "$result" || return 1
        echo "Switched to: $result"
    else
        # If switch failed, still run the command to show error
        portal switch "$@"
    fi
}

# Alias for quick worktree switching
alias pw='portal_cd'

# Portal prompt integration (optional)
_portal_prompt_command() {
    # Add current worktree info to prompt if in a worktree
    local worktree_info
    worktree_info=$(portal info --quiet 2>/dev/null)

    if [ $? -eq 0 ] && [ -n "$worktree_info" ]; then
        export PORTAL_WORKTREE_INFO="$worktree_info"
    else
        unset PORTAL_WORKTREE_INFO
    fi
}

# Uncomment to enable prompt integration
# autoload -Uz add-zsh-hook
# add-zsh-hook precmd _portal_prompt_command"""

    @staticmethod
    def install() -> tuple[bool, str]:
        """Install shell completions and functions.

        Returns:
            Tuple of (success, message)
        """
        shell = os.environ.get("SHELL", "").split("/")[-1]
        system = platform.system().lower()

        if shell == "bash":
            completion = ShellIntegration.get_bash_completion()
            if system == "darwin":  # macOS
                rc_file = Path.home() / ".bash_profile"
                if not rc_file.exists():
                    rc_file = Path.home() / ".bashrc"
            else:  # Linux
                rc_file = Path.home() / ".bashrc"
        elif shell == "zsh":
            completion = ShellIntegration.get_zsh_completion()
            rc_file = Path.home() / ".zshrc"
        else:
            return False, f"Unsupported shell: {shell}. Supported: bash, zsh"

        # Check if already installed
        if rc_file.exists():
            content = rc_file.read_text()
            if "Portal bash completion" in content or "Portal zsh completion" in content:
                return True, f"Already installed in {rc_file}"

        try:
            # Ensure rc file exists
            rc_file.touch()

            # Add to rc file
            with open(rc_file, "a") as f:
                f.write("\n# Portal CLI completion and functions (installed by Portal)\n")
                f.write(completion)
                f.write("\n")

            return (
                True,
                f"Installed to {rc_file}. Restart your shell or run: source {rc_file}",
            )

        except Exception as e:
            return False, f"Failed to write to {rc_file}: {e}"

    @staticmethod
    def uninstall() -> tuple[bool, str]:
        """Uninstall shell completions and functions.

        Returns:
            Tuple of (success, message)
        """
        shell = os.environ.get("SHELL", "").split("/")[-1]
        system = platform.system().lower()

        if shell == "bash":
            if system == "darwin":  # macOS
                rc_file = Path.home() / ".bash_profile"
                if not rc_file.exists():
                    rc_file = Path.home() / ".bashrc"
            else:  # Linux
                rc_file = Path.home() / ".bashrc"
        elif shell == "zsh":
            rc_file = Path.home() / ".zshrc"
        else:
            return False, f"Unsupported shell: {shell}"

        if not rc_file.exists():
            return True, "Shell integration not installed"

        try:
            content = rc_file.read_text()

            # Remove Portal completion section
            lines = content.split("\n")
            filtered_lines = []
            skip_section = False

            for line in lines:
                if "Portal CLI completion and functions" in line:
                    skip_section = True
                    continue
                elif skip_section and (
                    line.strip() == "" or line.startswith("#") or "portal" in line.lower()
                ):
                    continue
                else:
                    skip_section = False

                if not skip_section:
                    filtered_lines.append(line)

            # Write back
            rc_file.write_text("\n".join(filtered_lines))

            return True, f"Uninstalled from {rc_file}"

        except Exception as e:
            return False, f"Failed to modify {rc_file}: {e}"

    @staticmethod
    def get_installation_status() -> dict[str, Any]:
        """Get current installation status.

        Returns:
            Dictionary with installation status information
        """
        shell = os.environ.get("SHELL", "").split("/")[-1]
        system = platform.system().lower()

        if shell == "bash":
            if system == "darwin":  # macOS
                rc_file = Path.home() / ".bash_profile"
                if not rc_file.exists():
                    rc_file = Path.home() / ".bashrc"
            else:  # Linux
                rc_file = Path.home() / ".bashrc"
        elif shell == "zsh":
            rc_file = Path.home() / ".zshrc"
        else:
            return {
                "installed": False,
                "shell": shell,
                "config_file": None,
                "supported": False,
            }

        installed = False
        if rc_file.exists():
            content = rc_file.read_text()
            installed = "Portal bash completion" in content or "Portal zsh completion" in content

        return {
            "installed": installed,
            "shell": shell,
            "config_file": str(rc_file),
            "supported": shell in ["bash", "zsh"],
        }
