"""
venvy.commands.shell_init
~~~~~~~~~~~~~~~~~~~~~~~~~
Implements: venvy init-shell
Prints the shell integration snippet for the user to add to their profile.
"""

from __future__ import annotations

import platform
from pathlib import Path

from rich.console import Console
from rich.syntax import Syntax

from venvy.utils.shell import detect_shell, get_profile_path, get_shell_init_script

console = Console()

IS_WINDOWS = platform.system() == "Windows"


def cmd_init_shell(shell: str = "auto", write: bool = False) -> None:
    """
    Print or write the shell integration snippet.
    After this, `venvy +` activates and `venvy -` deactivates the venv.
    """
    if shell == "auto":
        shell = detect_shell()

    snippet = get_shell_init_script(shell)
    profile = get_profile_path(shell)

    console.print(f"\n[bold cyan]venvy[/bold cyan] — Shell Integration ({shell})\n")

    if write:
        _auto_write(shell, snippet, profile)
    else:
        console.print(
            f"Add the following to your [bold]{profile}[/bold]:\n"
        )
        lexer = "powershell" if shell in ("powershell", "pwsh") else "bash"
        console.print(Syntax(snippet, lexer, theme="monokai", line_numbers=False))
        console.print(
            f"\n[dim]Or run:[/dim] [bold cyan]venvy init-shell --write[/bold cyan] "
            f"[dim]to append automatically.[/dim]\n"
        )
        console.print(
            "After adding, restart your shell or run:\n"
            f"  [bold]source {_source_cmd(shell, profile)}[/bold]\n"
        )
        console.print(
            "Then use:\n"
            "  [bold cyan]venvy +[/bold cyan]  → activate\n"
            "  [bold cyan]venvy -[/bold cyan]  → deactivate\n"
        )


def _auto_write(shell: str, snippet: str, profile: str) -> None:
    """Attempt to auto-append the snippet to the shell profile."""
    if IS_WINDOWS and shell in ("powershell", "pwsh"):
        _write_powershell(snippet)
        return

    profile_path = _resolve_profile_path(shell)
    if not profile_path:
        console.print(
            f"[yellow]Could not auto-detect profile path for {shell}. "
            f"Please add manually to {profile}[/yellow]"
        )
        return

    # Check if already installed
    if profile_path.exists():
        existing = profile_path.read_text(encoding="utf-8")
        if "venvy shell integration" in existing:
            console.print(f"[green]✓[/green] Shell integration already in {profile_path}")
            return

    with open(profile_path, "a", encoding="utf-8") as f:
        f.write("\n" + snippet)

    console.print(f"[green]✓[/green] Shell integration added to {profile_path}")
    console.print(f"\nRestart your shell or run: [bold]source {profile_path}[/bold]")


def _resolve_profile_path(shell: str) -> Path | None:
    home = Path.home()
    mapping = {
        "bash": home / ".bashrc",
        "zsh": home / ".zshrc",
        "fish": home / ".config" / "fish" / "config.fish",
    }
    path = mapping.get(shell)
    if path:
        path.parent.mkdir(parents=True, exist_ok=True)
    return path


def _write_powershell(snippet: str) -> None:
    import subprocess
    result = subprocess.run(
        ["powershell", "-Command", "echo $PROFILE"],
        capture_output=True, text=True, check=False
    )
    profile_path = Path(result.stdout.strip())
    if not profile_path:
        console.print("[yellow]Could not find PowerShell profile path.[/yellow]")
        return
    profile_path.parent.mkdir(parents=True, exist_ok=True)
    if profile_path.exists():
        content = profile_path.read_text(encoding="utf-8")
        if "venvy shell integration" in content:
            console.print(f"[green]✓[/green] Shell integration already in {profile_path}")
            return
    with open(profile_path, "a", encoding="utf-8") as f:
        f.write("\n" + snippet)
    console.print(f"[green]✓[/green] Shell integration added to {profile_path}")


def _source_cmd(shell: str, profile: str) -> str:
    if shell in ("bash", "zsh", "sh"):
        return profile.split("  ")[0]  # strip notes
    return profile
