"""Requirements.txt management utilities."""
from __future__ import annotations
import re
import subprocess
from pathlib import Path
from typing import Dict, List, Optional


def parse_requirements(req_file: Path) -> Dict[str, str]:
    if not req_file.exists():
        return {}
    out: Dict[str, str] = {}
    for line in req_file.read_text(encoding="utf-8").splitlines():
        s = line.strip()
        if not s or s.startswith("#"):
            continue
        m = re.match(r"^([A-Za-z0-9_\-\.]+)", s)
        if m:
            out[m.group(1).lower().replace("-", "_")] = s
    return out


def write_requirements(req_file: Path, pkgs: Dict[str, str]) -> None:
    req_file.parent.mkdir(parents=True, exist_ok=True)
    req_file.write_text("\n".join(sorted(pkgs.values(), key=str.lower)) + "\n", encoding="utf-8")


def get_installed_version(python_exe: str, pkg: str) -> Optional[str]:
    result = subprocess.run([python_exe, "-m", "pip", "show", pkg], capture_output=True, text=True)
    for line in result.stdout.splitlines():
        if line.startswith("Version:"):
            return line.split(":", 1)[1].strip()
    return None


def add_to_requirements(packages: List[str], req_file: Path, python_exe: str) -> None:
    from venvy.utils.console import console
    if not req_file.exists():
        console.print(f"[green]✓[/green] Creating [bold]{req_file.name}[/bold]")
        req_file.touch()
    existing = parse_requirements(req_file)
    changed = False
    for pkg in packages:
        pkg_clean = re.split(r"[\[><=!;@\s]", pkg)[0].strip()
        if not pkg_clean or pkg_clean.startswith("-"):
            continue
        version = get_installed_version(python_exe, pkg_clean)
        if version:
            key = pkg_clean.lower().replace("-", "_")
            entry = f"{pkg_clean}=={version}"
            if existing.get(key) != entry:
                existing[key] = entry
                changed = True
                console.print(f"[green]+[/green] {entry} → [dim]{req_file.name}[/dim]")
    if changed:
        write_requirements(req_file, existing)


def remove_from_requirements(packages: List[str], req_file: Path) -> None:
    from venvy.utils.console import console
    if not req_file.exists():
        return
    existing = parse_requirements(req_file)
    changed = False
    for pkg in packages:
        pkg_clean = re.split(r"[\[><=!;@\s]", pkg)[0].strip()
        if not pkg_clean or pkg_clean.startswith("-"):
            continue
        key = pkg_clean.lower().replace("-", "_")
        if key in existing:
            existing.pop(key)
            changed = True
            console.print(f"[red]-[/red] {pkg_clean} → [dim]{req_file.name}[/dim]")
    if changed:
        write_requirements(req_file, existing)


def list_requirements(req_file: Path) -> None:
    from venvy.utils.console import console
    pkgs = parse_requirements(req_file)
    if not pkgs:
        console.print(f"[dim]No packages in {req_file.name if req_file else 'requirements.txt'}[/dim]")
        return
    console.print(f"\n[bold]Packages in {req_file.name}:[/bold]")
    for entry in sorted(pkgs.values()):
        console.print(f"  [cyan]•[/cyan] {entry}")
    console.print()
