"""
Module: init_command
Description: Pack initialization command with scaffolding

Implements:
    - docs/cli/reference.md#huitzo-init
"""

import re
from pathlib import Path
from typing import Optional

import httpx
import typer
from jinja2 import Environment, PackageLoader
from rich.console import Console

from huitzo_cli.auth import AuthClient
from huitzo_cli.config import ConfigManager

console = Console()


def validate_name(name: str) -> bool:
    """Validate pack name (lowercase with hyphens only)."""
    return bool(re.match(r"^[a-z0-9]([a-z0-9-]*[a-z0-9])?$", name))


def validate_namespace(namespace: str) -> bool:
    """Validate namespace (lowercase with hyphens only)."""
    return bool(re.match(r"^[a-z0-9]([a-z0-9-]*[a-z0-9])?$", namespace))


def name_to_module(name: str) -> str:
    """Convert pack name to Python module name."""
    return name.replace("-", "_")


def derive_username_slug(email: str) -> str | None:
    """Derive a valid username slug from email address.

    Args:
        email: User email address

    Returns:
        Valid slug string or None if derivation fails
    """
    if not email or "@" not in email:
        return None

    # Extract username part before @
    username = email.split("@")[0]

    # Sanitize: lowercase, replace underscores with hyphens
    slug = username.lower().replace("_", "-").replace(".", "-")

    # Remove any invalid characters
    slug = re.sub(r"[^a-z0-9-]", "", slug)

    # Ensure it starts with a letter
    if not slug or not slug[0].isalpha():
        return None

    # Remove leading/trailing hyphens
    slug = slug.strip("-")

    # Validate length (2-39 chars per backend requirements)
    if len(slug) < 2 or len(slug) > 39:
        return None

    # Final validation with our namespace regex
    if not validate_namespace(slug):
        return None

    return slug


def check_namespace_available(namespace: str, auth_client: AuthClient) -> tuple[bool, str | None]:
    """Check if namespace is available via backend API.

    Args:
        namespace: Namespace to check
        auth_client: Authenticated client

    Returns:
        Tuple of (available: bool, error_message: str | None)
    """
    token = auth_client.get_token()
    if not token:
        # Not authenticated - skip backend check, will validate during publish
        return True, None

    api_url = auth_client.get_api_url()
    try:
        resp = httpx.get(
            f"{api_url}/api/v1/namespaces/{namespace}/check",
            headers={"Authorization": f"Bearer {token}"},
            timeout=10,
        )
        if resp.status_code == 200:
            body = resp.json()
            data = body.get("data", {})
            return data.get("available", True), data.get("error")
    except httpx.HTTPError:
        # Network error - allow creation (backend will validate again during publish)
        pass

    return True, None


def init(
    name: Optional[str] = typer.Argument(None, help="Pack name (e.g., my-pack)"),
    namespace: Optional[str] = typer.Option(None, "--namespace", help="Pack namespace"),
    author: Optional[str] = typer.Option(None, "--author", help="Author name"),
    author_email: Optional[str] = typer.Option(None, "--email", help="Author email"),
    description: Optional[str] = typer.Option(None, "--description", help="Pack description"),
) -> None:
    """Initialize a new Intelligence Pack with scaffolding.

    Creates a project structure with:
    - pyproject.toml (package configuration)
    - huitzo.yaml (pack manifest)
    - Example command and tests
    - README and gitignore
    """
    # Get pack name
    if not name:
        name = typer.prompt("Pack name (lowercase, hyphens OK)")

    if not validate_name(name):
        console.print(
            "[red]❌ Invalid pack name. Use lowercase letters, numbers, and hyphens.[/red]"
        )
        raise typer.Exit(1)

    # Get namespace (default to username if authenticated, otherwise pack name)
    config_manager = ConfigManager()
    auth_client = AuthClient(config_manager)

    if not namespace:
        # Explain what a namespace is
        console.print(
            "\n[dim]→ Namespace is your unique identifier on Huitzo "
            "(e.g., @your-namespace/pack-name)[/dim]"
        )
        console.print("[dim]  You can reuse the same namespace for all your packs.[/dim]\n")

        # Try to get authenticated user's username
        default_namespace = name  # Fallback to pack name
        prompt_text = "Namespace"

        user_info = auth_client.get_current_user()
        if user_info:
            email = user_info.get("email", "")
            if email:
                username_slug = derive_username_slug(email)
                if username_slug:
                    default_namespace = username_slug
                    console.print(
                        f"[green]✓[/green] Using your username: [bold]{username_slug}[/bold]"
                    )
                    prompt_text = "Namespace (press Enter to confirm, or type a different one)"

        namespace = typer.prompt(prompt_text, default=default_namespace)

    if not validate_namespace(namespace):
        console.print(
            "[red]❌ Invalid namespace. Use lowercase letters, numbers, and hyphens.[/red]"
        )
        raise typer.Exit(1)

    # Check namespace availability via backend
    available, error = check_namespace_available(namespace, auth_client)
    if not available:
        console.print(f"[red]❌ {error}[/red]")
        raise typer.Exit(1)

    # ONLY check rate limit for NEW namespaces (available ones)
    # If namespace is available, it's a new namespace - check quota
    allowed, quota_error = config_manager.check_namespace_quota()
    if not allowed:
        console.print(f"[red]❌ {quota_error}[/red]")
        raise typer.Exit(1)

    # Get author info
    if not author:
        author = typer.prompt("Author name", default="Developer")

    if not author_email:
        author_email = typer.prompt("Author email", default="dev@example.com")

    # Get description
    if not description:
        description = typer.prompt("Description", default=f"Intelligence Pack: {name}")

    # Create project directory
    project_root = Path.cwd() / name
    if project_root.exists():
        console.print(f"[red]❌ Directory '{name}' already exists[/red]")
        raise typer.Exit(1)

    project_root.mkdir(parents=True, exist_ok=True)
    module_name = name_to_module(name)

    # Set up Jinja2 environment
    env = Environment(loader=PackageLoader("huitzo_cli", "templates/pack"))

    # Template context
    context = {
        "pack_name": name,
        "namespace": namespace,
        "module_name": module_name,
        "author": author,
        "author_email": author_email,
        "description": description,
    }

    # Create directory structure
    src_dir = project_root / "src" / module_name
    src_dir.mkdir(parents=True, exist_ok=True)

    commands_dir = src_dir / "commands"
    commands_dir.mkdir(parents=True, exist_ok=True)

    tests_dir = project_root / "tests"
    tests_dir.mkdir(parents=True, exist_ok=True)

    # Render templates
    files_to_create = {
        "pyproject.toml.j2": project_root / "pyproject.toml",
        "huitzo.yaml.j2": project_root / "huitzo.yaml",
        "README.md.j2": project_root / "README.md",
        ".gitignore.j2": project_root / ".gitignore",
        "__init__.py.j2": src_dir / "__init__.py",
        "hello.py.j2": commands_dir / "hello.py",
        "test_hello.py.j2": tests_dir / "test_hello.py",
        "conftest.py.j2": tests_dir / "conftest.py",
    }

    for template_name, target_path in files_to_create.items():
        template = env.get_template(template_name)
        content = template.render(**context)
        target_path.write_text(content)

    # Create __init__.py for commands directory with exports
    commands_init = '''"""Commands for this pack."""

from .hello import hello_world

__all__ = ["hello_world"]
'''
    (commands_dir / "__init__.py").write_text(commands_init)

    # Create __init__.py for tests directory
    (tests_dir / "__init__.py").write_text('"""Tests for this pack."""\n')

    # Create virtual environment
    console.print("\n[bold]Creating virtual environment...[/bold]")
    venv_dir = project_root / "venv"

    import subprocess
    import sys
    import shutil

    # Find Python 3.11+ (SDK requirement)
    python_exe = None
    for python_cmd in ["python3.13", "python3.12", "python3.11"]:
        found = shutil.which(python_cmd)
        if found:
            # Verify it's not a broken/rc version by testing it
            test_result = subprocess.run(
                [found, "--version"], capture_output=True, text=True, check=False
            )
            if test_result.returncode == 0 and "rc" not in test_result.stdout.lower():
                python_exe = found
                break

    if not python_exe:
        python_exe = sys.executable
        console.print(f"[yellow]⚠️  Python 3.11+ recommended, using {sys.executable}[/yellow]")

    try:
        subprocess.run([python_exe, "-m", "venv", str(venv_dir)], check=True)
        console.print(f"[green]✅ Virtual environment created (using {python_exe})[/green]")

        # Determine pip path based on OS
        import platform

        if platform.system() == "Windows":
            pip_path = venv_dir / "Scripts" / "pip"
        else:
            pip_path = venv_dir / "bin" / "pip"

        # Install huitzo-sdk
        console.print("[bold]Installing huitzo-sdk...[/bold]")

        # Try to find local SDK first (for development)
        sdk_path = Path.cwd().parent / "sdk"
        if not sdk_path.exists():
            # Try common locations
            for potential_sdk in [
                Path.home() / "huitzo-inc" / "sdk",
                Path("/home") / "esola-thomas" / "huitzo-inc" / "sdk",
            ]:
                if potential_sdk.exists():
                    sdk_path = potential_sdk
                    break

        install_cmd = [str(pip_path), "install"]
        if sdk_path.exists() and (sdk_path / "pyproject.toml").exists():
            # Install from local source
            install_cmd.extend(["-e", str(sdk_path)])
            console.print(f"[dim]Installing from local SDK: {sdk_path}[/dim]")
        else:
            # Try PyPI
            install_cmd.append("huitzo-sdk")

        install_result = subprocess.run(install_cmd, capture_output=True, text=True, check=False)

        if install_result.returncode == 0:
            console.print("[green]✅ huitzo-sdk installed[/green]")

            # Install dev dependencies
            console.print("[bold]Installing dev dependencies...[/bold]")
            dev_install = subprocess.run(
                [str(pip_path), "install", "pytest>=9.0", "pytest-asyncio>=1.0", "pytest-cov>=7.0"],
                capture_output=True,
                text=True,
                check=False,
            )
            if dev_install.returncode == 0:
                console.print("[green]✅ Dev dependencies installed[/green]")
        else:
            console.print("[yellow]⚠️  Could not install huitzo-sdk automatically[/yellow]")
            console.print(
                "[yellow]   Run: source venv/bin/activate && pip install huitzo-sdk[/yellow]"
            )

    except Exception as e:
        console.print(f"[yellow]⚠️  Could not create virtual environment: {e}[/yellow]")
        console.print("[yellow]   You can create it manually with: python -m venv venv[/yellow]")

    console.print(f"\n[green]✅ Pack '{name}' initialized successfully![/green]")
    console.print("\n[bold]Next steps:[/bold]")
    console.print(f"  cd {name}")
    console.print("  source venv/bin/activate  # On Windows: venv\\Scripts\\activate")
    console.print("  huitzo validate")
    console.print("  huitzo test")
    console.print("  huitzo dev")
