"""Backend registry and auto-detection."""

import os
from typing import Optional, Type

from scry_run.backends.base import GeneratorBackend
from scry_run.console import backend_selected


# Registry of available backends
_backends: dict[str, Type[GeneratorBackend]] = {}

# Auto-detection order (first available wins)
AUTO_DETECT_ORDER = ["claude"]


def register_backend(name: str, backend_cls: Type[GeneratorBackend]) -> None:
    """Register a backend class.

    Args:
        name: Backend name (e.g., "cli", "api")
        backend_cls: The backend class
    """
    _backends[name] = backend_cls


def get_backend(
    name: Optional[str] = None,
    model: Optional[str] = None,
) -> GeneratorBackend:
    """Get a backend instance.

    Args:
        name: Backend name to use. If None, auto-detect.
              Options: "claude", "frozen", "auto"
        model: Model name to use (backend-specific)

    Returns:
        Configured backend instance

    Raises:
        ValueError: If specified backend not found or unavailable
    """
    # Import backends here to trigger registration
    from scry_run.backends import claude, frozen

    # Check env var first
    env_backend = os.environ.get("SCRY_BACKEND", "").lower()
    if env_backend and name is None:
        name = env_backend

    # Auto-detect: try backends in priority order
    if name is None or name == "auto":
        for backend_name in AUTO_DETECT_ORDER:
            if backend_name in _backends and _backends[backend_name].is_available():
                backend_selected(backend_name, model, "auto-detected")
                return _backends[backend_name](model=model)
        raise ValueError(
            "No available backend. Install claude CLI."
        )

    # Specific backend requested
    if name not in _backends:
        raise ValueError(f"Unknown backend: {name}. Available: {list(_backends.keys())}")

    backend_cls = _backends[name]
    if not backend_cls.is_available():
        raise ValueError(f"Backend '{name}' is not available.")

    reason = "from SCRY_BACKEND" if env_backend else "explicit"
    backend_selected(name, model, reason)
    return backend_cls(model=model)
