"""Provider registry and active provider resolution."""

from __future__ import annotations

from typing import Any

from kiessclaw.providers.base import BaseProvider

ProviderClass = type[BaseProvider]
_PROVIDERS: dict[str, ProviderClass] = {}


def register_provider(name: str, provider_class: ProviderClass) -> None:
    """Register a provider class by name."""
    _PROVIDERS[name.strip().lower()] = provider_class


def get_provider(name: str, config: dict[str, Any] | None = None) -> BaseProvider | None:
    """Instantiate a provider by name."""
    provider_class = _PROVIDERS.get(name.strip().lower())
    if provider_class is None:
        return None
    return provider_class(config or {})


def list_providers() -> list[str]:
    """Return registered provider names in stable order."""
    return sorted(_PROVIDERS.keys())


def active_provider(
    kind: str,
    config: dict[str, Any] | None = None,
    preferred_name: str | None = None,
) -> BaseProvider | None:
    """Resolve active provider for a kind with mock fallback."""
    cfg = config or {}
    providers_cfg = cfg.get("providers", {}) if isinstance(cfg, dict) else {}
    configured = providers_cfg.get(kind) if isinstance(providers_cfg, dict) else None
    target_name = (preferred_name or configured or "mock").strip().lower()
    provider = get_provider(target_name, config=cfg)
    if provider is not None:
        return provider
    return get_provider("mock", config=cfg)


def register_builtin_providers() -> None:
    """Register bundled provider implementations."""
    from kiessclaw.providers.apollo import ApolloProvider
    from kiessclaw.providers.clay import ClayProvider
    from kiessclaw.providers.hunter import HunterProvider
    from kiessclaw.providers.hubspot import HubSpotProvider
    from kiessclaw.providers.mock import MockProvider

    register_provider("mock", MockProvider)
    register_provider("hunter", HunterProvider)
    register_provider("apollo", ApolloProvider)
    register_provider("clay", ClayProvider)
    register_provider("hubspot", HubSpotProvider)
