"""
venvy — the main CLI entry point.

Usage:
  venvy create venv               Create a virtual environment
  venvy pip install <pkg>         Install & track packages
  venvy pip uninstall <pkg>       Uninstall & remove from requirements
  venvy status                    Show project status
  venvy list                      List packages in requirements
  venvy sync                      Install all packages from requirements
  venvy shell-init                Print shell integration script
  venvy +                         Hint: activate venv (or use shell-init)
  venvy -                         Hint: deactivate venv (or use shell-init)
"""

from __future__ import annotations

from typing import List, Optional

import typer
from rich.panel import Panel
from rich import print as rprint

from venvy import __version__
from venvy.utils.console import console

# ── App definition ────────────────────────────────────────────────────
app = typer.Typer(
    name="venvy",
    help="Smart Python virtual environment manager — like package.json for Python.",
    add_completion=True,
    rich_markup_mode="rich",
    no_args_is_help=False,
)

create_app = typer.Typer(help="Create resources (venv, etc.)")
pip_app = typer.Typer(help="Pip wrapper that auto-updates requirements.txt")

app.add_typer(create_app, name="create")
app.add_typer(pip_app, name="pip")


# ── Version ───────────────────────────────────────────────────────────

def version_callback(value: bool) -> None:
    if value:
        console.print(f"[bold cyan]venvy[/bold cyan] v{__version__}")
        raise typer.Exit()


@app.callback(invoke_without_command=True)
def main(
    ctx: typer.Context,
    version: Optional[bool] = typer.Option(
        None,
        "--version",
        "-v",
        callback=version_callback,
        is_eager=True,
        help="Show version and exit.",
    ),
) -> None:
    """venvy — Smart Python virtual environment manager."""
    if ctx.invoked_subcommand is None:
        _print_welcome()


def _print_welcome() -> None:
    console.print(
        Panel.fit(
            f"[bold cyan]venvy[/bold cyan] v{__version__}\n"
            "[dim]Smart Python virtual environment manager[/dim]\n\n"
            "[bold]Quick start:[/bold]\n"
            "  [cyan]venvy create venv[/cyan]         — create & configure a venv\n"
            "  [cyan]venvy pip install <pkg>[/cyan]   — install + track package\n"
            "  [cyan]venvy pip uninstall <pkg>[/cyan] — uninstall + remove from reqs\n"
            "  [cyan]venvy status[/cyan]              — show current environment info\n"
            "  [cyan]venvy sync[/cyan]                — install all requirements\n"
            "  [cyan]venvy shell-init[/cyan]          — set up shell integration\n\n"
            "[dim]With shell integration:[/dim]\n"
            "  [cyan]venvy +[/cyan]  to activate   |  [cyan]venvy -[/cyan]  to deactivate",
            title="[bold]Welcome to venvy[/bold]",
            border_style="cyan",
        )
    )


# ── create venv ───────────────────────────────────────────────────────

@create_app.command("venv")
def create_venv(
    venv_name: str = typer.Option(
        ".venv",
        "--name",
        "-n",
        help="Name of the virtual environment directory.",
    ),
    req_file: str = typer.Option(
        "",
        "--requirements",
        "-r",
        help="Requirements file name (default: prompted, fallback requirements.txt).",
    ),
    ipykernel: bool = typer.Option(
        False,
        "--ipykernel/--no-ipykernel",
        help="Pre-select ipykernel installation.",
    ),
    yes: bool = typer.Option(
        False,
        "--yes",
        "-y",
        help="Skip prompts, use defaults.",
    ),
) -> None:
    """
    Create a virtual environment for the current project.

    Asks whether to install ipykernel and the requirements file name,
    then creates and activates the venv automatically.
    """
    from venvy.commands.create_cmd import create_venv_command
    create_venv_command(venv_name=venv_name, req_file=req_file, ipykernel=ipykernel, yes=yes)


# ── pip install ───────────────────────────────────────────────────────

@pip_app.command("install")
def pip_install(
    packages: List[str] = typer.Argument(..., help="Package(s) to install."),
    upgrade: bool = typer.Option(
        False, "--upgrade", "-U", help="Upgrade packages."
    ),
) -> None:
    """
    Install packages and automatically add them to requirements.txt.

    Example:
      venvy pip install requests httpx
    """
    from venvy.commands.pip_cmd import pip_install_command
    pip_install_command(packages=packages, upgrade=upgrade)


@pip_app.command("uninstall")
def pip_uninstall(
    packages: List[str] = typer.Argument(..., help="Package(s) to uninstall."),
    yes: bool = typer.Option(
        False, "--yes", "-y", help="Skip confirmation prompts."
    ),
) -> None:
    """
    Uninstall packages and automatically remove them from requirements.txt.

    Example:
      venvy pip uninstall requests
    """
    from venvy.commands.pip_cmd import pip_uninstall_command
    pip_uninstall_command(packages=packages, yes=yes)


# ── status ────────────────────────────────────────────────────────────

@app.command()
def status() -> None:
    """Show current virtual environment and requirements status."""
    from venvy.commands.status_cmd import status_command
    status_command()


# ── list ──────────────────────────────────────────────────────────────

@app.command("list")
def list_packages() -> None:
    """List all packages tracked in requirements.txt."""
    from pathlib import Path
    from venvy.core.config import load_config, find_project_root
    from venvy.core.requirements_manager import list_requirements

    cwd = Path.cwd()
    root = find_project_root(cwd)
    config = load_config(root) if root else None
    req_name = config.requirements_file if config else "requirements.txt"
    req_file = (root or cwd) / req_name
    list_requirements(req_file)


# ── sync ──────────────────────────────────────────────────────────────

@app.command()
def sync() -> None:
    """Install all packages listed in requirements.txt into the venv."""
    from pathlib import Path
    from venvy.core.config import load_config, find_project_root
    from venvy.core.requirements_manager import sync_requirements_to_venv
    from venvy.core.venv_manager import find_venv, get_venv_python
    from venvy.utils.platform_utils import get_active_venv
    import sys

    cwd = Path.cwd()
    root = find_project_root(cwd)
    config = load_config(root) if root else None
    req_name = config.requirements_file if config else "requirements.txt"
    req_file = (root or cwd) / req_name

    active = get_active_venv()
    if active:
        python_exe = str(get_venv_python(Path(active)))
    else:
        venv_path = find_venv(root or cwd)
        python_exe = str(get_venv_python(venv_path)) if venv_path else sys.executable

    sync_requirements_to_venv(req_file, python_exe)


# ── shell integration ─────────────────────────────────────────────────

@app.command("shell-init")
def shell_init() -> None:
    """
    Print shell integration script.

    Add to your shell config:
      eval "$(venvy shell-init)"    # bash/zsh

    Then use:
      venvy +   to activate
      venvy -   to deactivate
      pip install ...    auto-updates requirements (with shell integration)
    """
    from venvy.commands.shell_cmd import shell_init_command
    shell_init_command()


@app.command("_find-venv", hidden=True)
def _find_venv() -> None:
    """Internal: print venv path for shell functions."""
    from venvy.commands.shell_cmd import find_venv_command
    find_venv_command()


@app.command("+")
def activate_hint() -> None:
    """Show how to activate the virtual environment."""
    from venvy.commands.shell_cmd import activate_hint_command
    activate_hint_command()


@app.command("-")
def deactivate_hint() -> None:
    """Show how to deactivate the virtual environment."""
    from venvy.commands.shell_cmd import deactivate_hint_command
    deactivate_hint_command()
