"""Mushu SDK - Python clients for Mushu services."""

from typing import Any, Literal, overload

from mushu.auth.client import Client as AuthClient
from mushu.notify.client import Client as NotifyClient
from mushu.media.client import Client as MediaClient
from mushu.pay.client import Client as PayClient
from mushu.core.client import Client as CoreClient
from mushu.usage.client import Client as UsageClient
from mushu.geo.client import Client as GeoClient
from mushu.leaderboards.client import Client as LeaderboardsClient
from mushu.streaks.client import Client as StreaksClient
from mushu.geo_search.client import Client as Geo_searchClient

# Re-export commonly used core models
from mushu.core.models import ValidateApiKeyRequest, ValidateApiKeyResponse

# Hand-written wrapper clients (ergonomic APIs)
from mushu.wrappers import (
    AuthClient as AuthWrapper,
    NotifyClient as NotifyWrapper,
    MediaUrls,
)

# Helper functions for common operations
from mushu.helpers import can_access_org, can_manage_org, is_org_owner, validate_token_async

# Default service URLs
_SERVICE_URLS: dict[str, str] = {
    "auth": "https://auth.mushucorp.com",
    "notify": "https://notify.mushucorp.com",
    "media": "https://media.mushucorp.com",
    "pay": "https://pay.mushucorp.com",
    "core": "https://core.mushucorp.com",
    "usage": "https://usage.mushucorp.com",
    "geo": "https://geo.mushucorp.com",
    "leaderboards": "https://leaderboards.mushucorp.com",
    "streaks": "https://streaks.mushucorp.com",
    "geo_search": "https://geo_search.mushucorp.com",
}

# Generated client classes (for services without wrappers)
_GENERATED_CLIENTS: dict[str, type] = {
    "auth": AuthClient,
    "notify": NotifyClient,
    "media": MediaClient,
    "pay": PayClient,
    "core": CoreClient,
    "usage": UsageClient,
    "geo": GeoClient,
    "leaderboards": LeaderboardsClient,
    "streaks": StreaksClient,
    "geo_search": Geo_searchClient,
}


@overload
def client(
    service: Literal["auth"], base_url: str | None = None, api_key: str | None = None
) -> Any: ...

@overload
def client(
    service: Literal["notify"], base_url: str | None = None, api_key: str | None = None
) -> Any: ...

@overload
def client(
    service: Literal["media"], base_url: str | None = None, api_key: str | None = None
) -> Any: ...

@overload
def client(
    service: Literal["pay"], base_url: str | None = None, api_key: str | None = None
) -> Any: ...

@overload
def client(
    service: Literal["core"], base_url: str | None = None, api_key: str | None = None
) -> Any: ...

@overload
def client(
    service: Literal["usage"], base_url: str | None = None, api_key: str | None = None
) -> Any: ...

@overload
def client(
    service: Literal["geo"], base_url: str | None = None, api_key: str | None = None
) -> Any: ...

@overload
def client(
    service: Literal["leaderboards"], base_url: str | None = None, api_key: str | None = None
) -> Any: ...

@overload
def client(
    service: Literal["streaks"], base_url: str | None = None, api_key: str | None = None
) -> Any: ...

@overload
def client(
    service: Literal["geo_search"], base_url: str | None = None, api_key: str | None = None
) -> Any: ...


def client(service: str, base_url: str | None = None, api_key: str | None = None):
    """Factory to get a typed client for any Mushu service.

    For auth and notify, returns hand-written wrapper clients. For all other
    services (including media), returns the generated client with api_key
    set via X-API-Key header.

    Args:
        service: Service name (auth, notify, media, pay, etc.)
        base_url: Override the default service URL
        api_key: API key — sets the X-API-Key header automatically
    """
    if service not in _SERVICE_URLS:
        raise ValueError(f"Unknown service: {service}")

    url = base_url or _SERVICE_URLS[service]

    # Services with hand-written wrappers get ergonomic clients
    if service == "notify" and api_key:
        return NotifyWrapper(api_key=api_key, app_id="", base_url=url)
    if service == "auth":
        return AuthWrapper(auth_url=url)

    # All other services get the generated client
    cls = _GENERATED_CLIENTS[service]
    c = cls(base_url=url)
    if api_key:
        c = c.with_headers({"X-API-Key": api_key})
    return c


__all__ = [
    "client",
    # Generated clients (low-level)
    "AuthClient",
    "NotifyClient",
    "MediaClient",
    "PayClient",
    "CoreClient",
    "UsageClient",
    "GeoClient",
    "LeaderboardsClient",
    "StreaksClient",
    "Geo_searchClient",
    # Wrapper clients (ergonomic APIs)
    "AuthWrapper",
    "NotifyWrapper",
    "MediaUrls",
    # Core models
    "ValidateApiKeyRequest",
    "ValidateApiKeyResponse",
    # Helper functions
    "validate_token_async",
    "can_manage_org",
    "can_access_org",
    "is_org_owner",
]