"""Virtual environment creation and hook injection."""
from __future__ import annotations
import platform
import subprocess
import sys
from pathlib import Path
from typing import Optional

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


def get_venv_python(venv_path: Path) -> Path:
    if IS_WINDOWS:
        return venv_path / "Scripts" / "python.exe"
    return venv_path / "bin" / "python"


def get_venv_site_packages(venv_path: Path) -> Optional[Path]:
    python = get_venv_python(venv_path)
    if not python.exists():
        return None
    result = subprocess.run(
        [str(python), "-c",
         "import site; sp=[p for p in site.getsitepackages() if 'site-packages' in p]; print(sp[0] if sp else '')"],
        capture_output=True, text=True,
    )
    if result.returncode == 0 and result.stdout.strip():
        return Path(result.stdout.strip())
    return None


def inject_hook(venv_path: Path) -> bool:
    from venvy.core.hook import get_hook_files
    site_packages = get_venv_site_packages(venv_path)
    if not site_packages or not site_packages.exists():
        return False
    hook_py, hook_pth = get_hook_files()
    (site_packages / "venvy_hook.py").write_text(hook_py, encoding="utf-8")
    (site_packages / "venvy_hook.pth").write_text(hook_pth, encoding="utf-8")
    return True


def create_venv(cwd: Path, config: "VenvyConfig") -> bool:  # type: ignore[name-defined]
    from venvy.core.config import save_config
    from venvy.utils.console import console

    venv_path = cwd / config.venv_name
    if venv_path.exists():
        console.print(f"[yellow]⚠[/yellow]  Venv already exists at [bold]{venv_path}[/bold]")
        return False

    console.print(f"[cyan]→[/cyan] Creating virtual environment [bold]{config.venv_name}[/bold]...")
    result = subprocess.run([sys.executable, "-m", "venv", str(venv_path)], capture_output=True, text=True)
    if result.returncode != 0:
        console.print(f"[red]✗[/red] Failed:\n{result.stderr}")
        return False
    console.print("[green]✓[/green] Virtual environment created.")

    python = get_venv_python(venv_path)
    subprocess.run([str(python), "-m", "pip", "install", "--upgrade", "pip", "-q"], capture_output=True)

    console.print("[cyan]→[/cyan] Installing pip auto-tracking hook...")
    if inject_hook(venv_path):
        console.print(
            "[green]✓[/green] Hook installed — [bold]pip install[/bold] and "
            "[bold]pip uninstall[/bold] will auto-update requirements.txt"
        )
    else:
        console.print("[yellow]⚠[/yellow]  Hook injection failed — use [bold]venvy pip install[/bold] as fallback")

    if config.install_ipykernel:
        console.print("[cyan]→[/cyan] Installing ipykernel...")
        r = subprocess.run([str(python), "-m", "pip", "install", "ipykernel", "-q"], capture_output=True, text=True)
        if r.returncode == 0:
            subprocess.run([str(python), "-m", "ipykernel", "install", "--user",
                            f"--name={cwd.name}", "--display-name", cwd.name], capture_output=True)
            console.print(f"[green]✓[/green] ipykernel registered as [bold]{cwd.name}[/bold]")
        else:
            console.print("[yellow]⚠[/yellow]  ipykernel failed — skipping")

    req_file = cwd / config.requirements_file
    if req_file.exists() and req_file.stat().st_size > 0:
        console.print(f"[cyan]→[/cyan] Installing from [bold]{config.requirements_file}[/bold]...")
        subprocess.run([str(python), "-m", "pip", "install", "-r", str(req_file), "-q"], capture_output=True)
        console.print("[green]✓[/green] Packages installed.")

    save_config(config, cwd)
    _print_activation(venv_path)
    return True


def _print_activation(venv_path: Path) -> None:
    from venvy.utils.console import console
    if IS_WINDOWS:
        console.print(
            f"\n[bold green]✓ Ready![/bold green] Activate with:\n"
            f"  [bold cyan]{venv_path}\\Scripts\\activate[/bold cyan]   (PowerShell)\n"
            f"  [bold cyan]{venv_path}\\Scripts\\activate.bat[/bold cyan]  (CMD)\n"
        )
    else:
        console.print(
            f"\n[bold green]✓ Ready![/bold green] Activate with:\n"
            f"  [bold cyan]source {venv_path}/bin/activate[/bold cyan]\n"
        )


def find_venv(cwd: Optional[Path] = None) -> Optional[Path]:
    from venvy.core.config import load_config, find_project_root
    base = cwd or Path.cwd()
    root = find_project_root(base)
    if root:
        cfg = load_config(root)
        if cfg:
            venv_path = root / cfg.venv_name
            if venv_path.exists() and get_venv_python(venv_path).exists():
                return venv_path
    for name in (".venv", "venv", "env", ".env"):
        candidate = base / name
        if candidate.is_dir() and get_venv_python(candidate).exists():
            return candidate
    return None
