"""xnv CLI — Python virtual environment doctor."""

from __future__ import annotations

import argparse
import sys
from pathlib import Path

from xnv import __version__
from xnv.diagnose import diagnose
from xnv.fix import (
    NC, BOLD, GREEN, RED, YELLOW, BLUE,
    _print_issue, nuke_venv, create_venv, fix, fix_poetry_lock,
)


def cmd_doctor(args: argparse.Namespace) -> int:
    """Diagnose environment health."""
    project_dir = Path(args.path).resolve()
    print(f"\n{BOLD}xnv doctor{NC} — {project_dir}\n")

    diag = diagnose(project_dir)

    for issue in diag.issues:
        _print_issue(issue)

    print()
    errors = diag.errors
    warnings = diag.warnings
    total = len(diag.issues)
    info_count = total - len(errors) - len(warnings)

    summary_parts = []
    if errors:
        summary_parts.append(f"{RED}{len(errors)} errors{NC}")
    if warnings:
        summary_parts.append(f"{YELLOW}{len(warnings)} warnings{NC}")
    if info_count:
        summary_parts.append(f"{GREEN}{info_count} ok{NC}")

    print(f"  {' / '.join(summary_parts)}")

    if not errors:
        print(f"\n{GREEN}{BOLD}✓ Environment healthy{NC}")
        return 0
    else:
        print(f"\n{RED}{BOLD}✗ Issues found — run 'xnv fix' to repair{NC}")
        return 1


def cmd_fix(args: argparse.Namespace) -> int:
    """Fix environment issues."""
    ok = fix(
        project_dir=args.path,
        force_recreate=args.force,
        install=not args.no_install,
        dev=args.dev,
    )
    return 0 if ok else 1


def cmd_nuke(args: argparse.Namespace) -> int:
    """Remove venv completely."""
    project_dir = Path(args.path).resolve()
    venv_name = args.name
    print(f"\n{BOLD}xnv nuke{NC} — {project_dir / venv_name}\n")
    nuke_venv(project_dir, venv_name)
    return 0


def cmd_create(args: argparse.Namespace) -> int:
    """Create fresh venv."""
    project_dir = Path(args.path).resolve()
    venv_name = args.name
    print(f"\n{BOLD}xnv create{NC} — {project_dir / venv_name}\n")

    venv_path = project_dir / venv_name
    if venv_path.exists():
        if not args.force:
            print(f"  {YELLOW}Venv already exists.{NC} Use --force to recreate.")
            return 1
        nuke_venv(project_dir, venv_name)

    ok = create_venv(project_dir, venv_name)
    if ok:
        print(f"\n  Activate: {BLUE}source {venv_path}/bin/activate{NC}")
    return 0 if ok else 1


def cmd_lock(args: argparse.Namespace) -> int:
    """Fix poetry.lock."""
    project_dir = Path(args.path).resolve()
    print(f"\n{BOLD}xnv lock{NC} — {project_dir}\n")
    ok = fix_poetry_lock(project_dir)
    return 0 if ok else 1


def build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        prog="xnv",
        description="Python virtual environment doctor — diagnose and fix broken venvs",
    )
    parser.add_argument("--version", action="version", version=f"xnv {__version__}")

    sub = parser.add_subparsers(dest="command", help="Available commands")

    # doctor
    p_doctor = sub.add_parser("doctor", help="Diagnose environment health")
    p_doctor.add_argument("path", nargs="?", default=".", help="Project directory (default: .)")

    # fix
    p_fix = sub.add_parser("fix", help="Diagnose and fix environment issues")
    p_fix.add_argument("path", nargs="?", default=".", help="Project directory (default: .)")
    p_fix.add_argument("--force", "-f", action="store_true", help="Force recreate venv even if healthy")
    p_fix.add_argument("--no-install", action="store_true", help="Skip dependency installation")
    p_fix.add_argument("--dev", action="store_true", help="Install dev dependencies too")

    # nuke
    p_nuke = sub.add_parser("nuke", help="Remove virtual environment")
    p_nuke.add_argument("path", nargs="?", default=".", help="Project directory (default: .)")
    p_nuke.add_argument("--name", "-n", default="venv", help="Venv directory name (default: venv)")

    # create
    p_create = sub.add_parser("create", help="Create fresh virtual environment")
    p_create.add_argument("path", nargs="?", default=".", help="Project directory (default: .)")
    p_create.add_argument("--name", "-n", default="venv", help="Venv directory name (default: venv)")
    p_create.add_argument("--force", "-f", action="store_true", help="Recreate if exists")

    # lock
    p_lock = sub.add_parser("lock", help="Regenerate poetry.lock")
    p_lock.add_argument("path", nargs="?", default=".", help="Project directory (default: .)")

    return parser


COMMANDS = {
    "doctor": cmd_doctor,
    "fix": cmd_fix,
    "nuke": cmd_nuke,
    "create": cmd_create,
    "lock": cmd_lock,
}


def main(argv: list[str] | None = None) -> int:
    parser = build_parser()
    args = parser.parse_args(argv)

    if not args.command:
        # Default to doctor
        args.command = "doctor"
        args.path = "."

    handler = COMMANDS.get(args.command)
    if handler:
        return handler(args)

    parser.print_help()
    return 1


if __name__ == "__main__":
    sys.exit(main())
