"""The initialised SDK client."""

from __future__ import annotations

from typing import Any, Optional
from urllib.parse import quote

from .auth import Audience, TokenVerifier
from .config import ResolvedConfig, resolve_config
from .http import HttpClient
from .types import PartnerEcosystemConfig


class PartnerEcosystemClient:
    """The initialised SDK instance.

    Create one at start-up with :func:`ab_ecosystem.init` and reuse it for the
    lifetime of the process.
    """

    def __init__(self, config: PartnerEcosystemConfig) -> None:
        self.config: ResolvedConfig = resolve_config(config)
        self._http = HttpClient(self.config)
        #: JWKS-backed token verifier (the Node middleware's core).
        self.verifier = TokenVerifier(self.config)

    # -- Server-to-server actions ------------------------------------------

    def ping(self) -> Any:
        """Health check against the API using the project credentials."""
        return self._http.request("/ping")

    # -- User-scoped endpoints --------------------------------------------

    def get_user_profile(self, access_token: Optional[str] = None) -> Any:
        """``GET /api/v1/projects/:project_id/me``"""
        return self._http.request(
            self._project_path("me"), headers=_bearer(access_token)
        )

    def get_user_wallet(self, access_token: Optional[str] = None) -> Any:
        """``GET /api/v1/projects/:project_id/me``"""
        return self._http.request(
            self._project_path("me"), headers=_bearer(access_token)
        )

    def get_user_credit_wallet(self, access_token: Optional[str] = None) -> Any:
        """``GET /api/v1/projects/:project_id/credit-wallets``"""
        return self._http.request(
            self._project_path("credit-wallets"), headers=_bearer(access_token)
        )

    def get_user_subscription(self, access_token: Optional[str] = None) -> Any:
        """``GET /api/v1/projects/:project_id/subscription``"""
        return self._http.request(
            self._project_path("subscription"), headers=_bearer(access_token)
        )

    # -- Auth --------------------------------------------------------------

    def verify_token(
        self,
        token: str,
        *,
        audience: Optional[Audience] = None,
        issuer: Optional[str] = None,
    ) -> dict[str, Any]:
        """Verify a bearer JWT against the project's JWKS endpoint."""
        return self.verifier.verify(token, audience=audience, issuer=issuer)

    def close(self) -> None:
        """Release the underlying HTTP connection pool."""
        self._http.close()

    # -- Internals ---------------------------------------------------------

    def _project_path(self, suffix: str) -> str:
        return f"/api/v1/projects/{quote(self.config.project_id, safe='')}/{suffix}"


def _bearer(access_token: Optional[str]) -> Optional[dict[str, str]]:
    if not access_token:
        return None
    return {"authorization": f"Bearer {access_token}"}
