"""
Webhooks Resource

Manage webhooks — create, list, update, delete, activate, and deactivate.
"""

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 (
    Webhook,
    WebhookDeleteResponse,
    WebhookListResponse,
    WebhookResponse,
)
from ..types.inputs import WebhookCreateInput, WebhookUpdateInput

if TYPE_CHECKING:
    from ..lib.transport import Transport


class WebhooksResource:
    """
    Webhooks resource.

    Provides methods to manage webhook registrations for receiving
    event notifications.
    """

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

    async def list(self, sensor: str | None = None) -> list[Webhook]:
        """
        List webhooks, optionally filtered by sensor.

        Args:
            sensor: Optional sensor ID to filter by

        Returns:
            Array of registered webhooks
        """
        params: dict[str, str] = {}
        if sensor:
            params["sensor"] = sensor

        result = await self._transport.get(
            self._transport.paths.webhook_list,
            params=params or None,
        )
        response = WebhookListResponse.model_validate(result)
        return response.webhooks

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

        Args:
            id: The webhook UUID

        Returns:
            The webhook object
        """
        validate_non_empty_string(id, "webhookId")

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

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

        Args:
            input: Webhook configuration

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

        result = await self._transport.post(
            self._transport.paths.webhook_create,
            payload,
        )
        response = WebhookResponse.model_validate(result)
        return response.webhook

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

        Args:
            id: The webhook UUID
            input: Updated webhook configuration

        Returns:
            The updated webhook
        """
        validate_non_empty_string(id, "webhookId")
        validate_with_schema(WebhookUpdateInput, input, "webhook")
        payload = serialize_input(input, WebhookUpdateInput)

        path = self._transport.paths.webhook_update.replace("{id}", quote(id, safe=""))
        result = await self._transport.put(path, payload)
        response = WebhookResponse.model_validate(result)
        return response.webhook

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

        Args:
            id: The webhook UUID

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

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

    async def activate(self, id: str) -> Webhook:
        """
        Activate a webhook.

        Args:
            id: The webhook UUID

        Returns:
            The activated webhook
        """
        validate_non_empty_string(id, "webhookId")

        path = self._transport.paths.webhook_activate.replace("{id}", quote(id, safe=""))
        result = await self._transport.put(path)
        response = WebhookResponse.model_validate(result)
        return response.webhook

    async def deactivate(self, id: str) -> Webhook:
        """
        Deactivate a webhook.

        Args:
            id: The webhook UUID

        Returns:
            The deactivated webhook
        """
        validate_non_empty_string(id, "webhookId")

        path = self._transport.paths.webhook_deactivate.replace("{id}", quote(id, safe=""))
        result = await self._transport.put(path)
        response = WebhookResponse.model_validate(result)
        return response.webhook
