"""
Timeback Webhooks Client

Async client for managing webhook registrations and filters.
"""

from __future__ import annotations

from typing import TYPE_CHECKING, Literal, Protocol, cast

from .lib.transport import Transport
from .resources.webhook_filters import WebhookFiltersResource
from .resources.webhooks import WebhooksResource

if TYPE_CHECKING:
    from timeback_common import AuthCheckResult, Environment, TimebackProvider, WebhookPaths

Platform = Literal["BEYOND_AI", "LEARNWITH_AI"]


class WebhooksTransportLike(Protocol):
    """Duck-typed transport interface for custom transports."""

    base_url: str
    paths: WebhookPaths

    async def close(self) -> None: ...


class WebhooksClient:
    """
    Webhooks API client for managing webhook registrations and filters.

    Provides access to webhook CRUD operations, activation/deactivation,
    and webhook filter management.

    Example: Environment mode (Timeback APIs)
        ```python
        client = WebhooksClient(
            env="staging",
            client_id="your-client-id",
            client_secret="your-client-secret",
        )
        ```

    Example: Managing webhooks
        ```python
        webhook = await client.webhooks.create({
            "name": "My Webhook",
            "targetUrl": "https://myapp.example.com/events",
            "secret": "my-shared-secret",
            "active": True,
        })

        await client.webhook_filters.create({
            "webhookId": webhook.id,
            "filterKey": "type",
            "filterValue": "ActivityEvent",
            "filterType": "string",
            "filterOperator": "eq",
            "active": True,
        })
        ```
    """

    def __init__(
        self,
        *,
        platform: Platform | None = None,
        env: str | None = None,
        transport: WebhooksTransportLike | None = None,
        base_url: str | None = None,
        auth_url: str | None = None,
        client_id: str | None = None,
        client_secret: str | None = None,
        timeout: float = 30.0,
        provider: TimebackProvider | None = None,
    ) -> None:
        self._transport: Transport | WebhooksTransportLike
        if transport is not None:
            self._transport = transport
            self._provider = None
        else:
            from timeback_common import EnvVarNames, build_provider_env, build_provider_explicit

            env_vars = EnvVarNames(
                base_url=(
                    "TIMEBACK_API_BASE_URL",
                    "TIMEBACK_BASE_URL",
                    "WEBHOOKS_BASE_URL",
                ),
                auth_url=(
                    "TIMEBACK_API_AUTH_URL",
                    "TIMEBACK_AUTH_URL",
                    "WEBHOOKS_TOKEN_URL",
                ),
                client_id=(
                    "TIMEBACK_API_CLIENT_ID",
                    "TIMEBACK_CLIENT_ID",
                    "WEBHOOKS_CLIENT_ID",
                ),
                client_secret=(
                    "TIMEBACK_API_CLIENT_SECRET",
                    "TIMEBACK_CLIENT_SECRET",
                    "WEBHOOKS_CLIENT_SECRET",
                ),
            )

            if provider is None:
                if env is not None:
                    provider = build_provider_env(
                        platform=platform,
                        env=cast("Environment", env),
                        client_id=client_id,
                        client_secret=client_secret,
                        timeout=timeout,
                        env_vars=env_vars,
                    )
                else:
                    provider = build_provider_explicit(
                        base_url=base_url,
                        auth_url=auth_url,
                        client_id=client_id,
                        client_secret=client_secret,
                        timeout=timeout,
                        env_vars=env_vars,
                    )

            self._provider = provider

            endpoint = provider.get_endpoint("webhooks")
            paths = provider.get_paths("webhooks")
            token_manager = provider.get_token_manager("webhooks")

            self._transport = Transport(
                base_url=endpoint.base_url,
                token_manager=token_manager,
                paths=paths,
                timeout=provider.timeout,
                no_auth=token_manager is None,
            )

        if not hasattr(self._transport, "paths"):
            raise TypeError(
                "Custom transport must have a 'paths' attribute with Webhook path "
                "configuration. Use the Webhooks Transport class or ensure your "
                "transport includes a WebhookPaths instance."
            )

        _transport = cast("Transport", self._transport)
        self.webhooks = WebhooksResource(_transport)
        self.webhook_filters = WebhookFiltersResource(_transport)

    def get_transport(self) -> Transport | WebhooksTransportLike:
        """Get the underlying transport for advanced use cases."""
        return self._transport

    async def check_auth(self) -> AuthCheckResult:
        """
        Verify that OAuth authentication is working.

        Raises:
            RuntimeError: If client was initialized without a provider
        """
        if self._provider is None:
            raise RuntimeError("Cannot check auth: client initialized without provider")
        return await self._provider.check_auth()

    async def close(self) -> None:
        """Close the HTTP client and release resources."""
        await self._transport.close()

    async def __aenter__(self) -> WebhooksClient:
        return self

    async def __aexit__(
        self,
        exc_type: type[BaseException] | None,
        exc_val: BaseException | None,
        exc_tb: object | None,
    ) -> None:
        await self.close()
