"""
Webhook Filters Resource

Manage webhook filters — create, list, update, and delete.
"""

from __future__ import annotations

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

from timeback_common import (
    NotFoundError,
    serialize_input,
    validate_non_empty_string,
    validate_with_schema,
)

from ..types.api import (
    WebhookFilter,
    WebhookFilterDeleteResponse,
    WebhookFilterListResponse,
    WebhookFilterResponse,
)
from ..types.inputs import WebhookFilterCreateInput, WebhookFilterUpdateInput

if TYPE_CHECKING:
    from ..lib.transport import Transport


class WebhookFiltersResource:
    """
    Webhook Filters resource.

    Provides methods to manage filters that control which events
    trigger webhook delivery.
    """

    def __init__(self, transport: Transport) -> None:
        self._transport = transport

    async def list(self) -> list[WebhookFilter]:
        """
        List all webhook filters.

        Returns:
            Array of all webhook filters
        """
        result = await self._transport.get(self._transport.paths.webhook_filter_list)
        response = WebhookFilterListResponse.model_validate(result)
        return response.filters

    async def get(self, id: str) -> WebhookFilter:
        """
        Get a specific webhook filter by ID.

        Args:
            id: The webhook filter ID

        Returns:
            The webhook filter object
        """
        validate_non_empty_string(id, "webhookFilterId")

        path = self._transport.paths.webhook_filter_get.replace("{id}", quote(id, safe=""))
        result = await self._transport.get(path)
        if not result or "filter" not in result:
            raise NotFoundError(f"Webhook filter not found: {id}")
        response = WebhookFilterResponse.model_validate(result)
        return response.filter

    async def list_by_webhook(self, webhook_id: str) -> list[WebhookFilter]:
        """
        List all filters for a specific webhook.

        Args:
            webhook_id: The parent webhook UUID

        Returns:
            Array of filters for the specified webhook
        """
        validate_non_empty_string(webhook_id, "webhookId")

        path = self._transport.paths.webhook_filters_by_webhook.replace(
            "{webhookId}", quote(webhook_id, safe="")
        )
        result = await self._transport.get(path)
        response = WebhookFilterListResponse.model_validate(result)
        return response.filters

    async def create(self, input: WebhookFilterCreateInput | dict[str, Any]) -> WebhookFilter:
        """
        Create a new webhook filter.

        Args:
            input: Filter configuration

        Returns:
            The created webhook filter
        """
        validate_with_schema(WebhookFilterCreateInput, input, "webhook filter")
        payload = serialize_input(input, WebhookFilterCreateInput)

        result = await self._transport.post(
            self._transport.paths.webhook_filter_create,
            payload,
        )
        response = WebhookFilterResponse.model_validate(result)
        return response.filter

    async def update(
        self, id: str, input: WebhookFilterUpdateInput | dict[str, Any]
    ) -> WebhookFilter:
        """
        Update an existing webhook filter.

        Args:
            id: The webhook filter ID
            input: Updated filter configuration

        Returns:
            The updated webhook filter
        """
        validate_non_empty_string(id, "webhookFilterId")
        validate_with_schema(WebhookFilterUpdateInput, input, "webhook filter")
        payload = serialize_input(input, WebhookFilterUpdateInput)

        path = self._transport.paths.webhook_filter_update.replace("{id}", quote(id, safe=""))
        result = await self._transport.put(path, payload)
        response = WebhookFilterResponse.model_validate(result)
        return response.filter

    async def delete(self, id: str) -> WebhookFilterDeleteResponse:
        """
        Delete a webhook filter.

        Args:
            id: The webhook filter ID

        Returns:
            The delete response with status
        """
        validate_non_empty_string(id, "webhookFilterId")

        path = self._transport.paths.webhook_filter_delete.replace("{id}", quote(id, safe=""))
        result = await self._transport.request("DELETE", path)
        return WebhookFilterDeleteResponse.model_validate(result)
