from typing import Any

from .._base import AsyncBaseResource, AsyncPageIterator, BaseResource, PageIterator, unwrap_response
from ..models import Webhook, WebhookDelivery, WebhookEvent


class Webhooks(BaseResource):
    _path = "/air/webhooks"

    def list(self, *, limit: int | None = None) -> PageIterator[Webhook]:
        return self._list(Webhook, params={"limit": limit})

    def get(self, id: str) -> Webhook:
        return self._get(id, Webhook)

    def create(self, *, url: str, events: "list[str]") -> Webhook:
        return self._create(Webhook, {"url": url, "events": events})

    def update(
        self,
        id: str,
        *,
        active: bool | None = None,
        events: "list[str] | None" = None,
        url: str | None = None,
    ) -> Webhook:
        data: dict[str, Any] = {}
        if active is not None:
            data["active"] = active
        if events is not None:
            data["events"] = events
        if url is not None:
            data["url"] = url
        return self._update(id, Webhook, data)

    def delete(self, id: str) -> None:
        self._delete(id)

    def ping(self, id: str) -> None:
        resp = self._transport.request("POST", f"{self._path}/{id}/actions/ping")
        unwrap_response(resp)


class WebhookDeliveries(BaseResource):
    _path = "/air/webhooks/deliveries"

    def list(
        self,
        *,
        limit: int | None = None,
        type: str | None = None,
        delivery_success: bool | None = None,
        endpoint_id: str | None = None,
    ) -> PageIterator[WebhookDelivery]:
        return self._list(
            WebhookDelivery,
            params={"limit": limit, "type": type, "delivery_success": delivery_success,
                    "endpoint_id": endpoint_id},
        )

    def get(self, id: str) -> WebhookDelivery:
        return self._get(id, WebhookDelivery)


class WebhookEvents(BaseResource):
    _path = "/air/webhooks/events"

    def list(
        self,
        *,
        limit: int | None = None,
        type: str | None = None,
        delivery_success: bool | None = None,
    ) -> PageIterator[WebhookEvent]:
        return self._list(
            WebhookEvent,
            params={"limit": limit, "type": type, "delivery_success": delivery_success},
        )

    def get(self, id: str) -> WebhookEvent:
        return self._get(id, WebhookEvent)

    def redeliver(self, id: str) -> None:
        resp = self._transport.request("POST", f"{self._path}/{id}/actions/redeliver")
        unwrap_response(resp)


class AsyncWebhooks(AsyncBaseResource):
    _path = "/air/webhooks"

    def list(self, *, limit: int | None = None) -> AsyncPageIterator[Webhook]:
        return self._list(Webhook, params={"limit": limit})

    async def get(self, id: str) -> Webhook:
        return await self._get(id, Webhook)

    async def create(self, *, url: str, events: "list[str]") -> Webhook:
        return await self._create(Webhook, {"url": url, "events": events})

    async def update(
        self,
        id: str,
        *,
        active: bool | None = None,
        events: "list[str] | None" = None,
        url: str | None = None,
    ) -> Webhook:
        data: dict[str, Any] = {}
        if active is not None:
            data["active"] = active
        if events is not None:
            data["events"] = events
        if url is not None:
            data["url"] = url
        return await self._update(id, Webhook, data)

    async def delete(self, id: str) -> None:
        await self._delete(id)

    async def ping(self, id: str) -> None:
        resp = await self._transport.request("POST", f"{self._path}/{id}/actions/ping")
        unwrap_response(resp)


class AsyncWebhookDeliveries(AsyncBaseResource):
    _path = "/air/webhooks/deliveries"

    def list(
        self,
        *,
        limit: int | None = None,
        type: str | None = None,
        delivery_success: bool | None = None,
        endpoint_id: str | None = None,
    ) -> AsyncPageIterator[WebhookDelivery]:
        return self._list(
            WebhookDelivery,
            params={"limit": limit, "type": type, "delivery_success": delivery_success,
                    "endpoint_id": endpoint_id},
        )

    async def get(self, id: str) -> WebhookDelivery:
        return await self._get(id, WebhookDelivery)


class AsyncWebhookEvents(AsyncBaseResource):
    _path = "/air/webhooks/events"

    def list(
        self,
        *,
        limit: int | None = None,
        type: str | None = None,
        delivery_success: bool | None = None,
    ) -> AsyncPageIterator[WebhookEvent]:
        return self._list(
            WebhookEvent,
            params={"limit": limit, "type": type, "delivery_success": delivery_success},
        )

    async def get(self, id: str) -> WebhookEvent:
        return await self._get(id, WebhookEvent)

    async def redeliver(self, id: str) -> None:
        resp = await self._transport.request("POST", f"{self._path}/{id}/actions/redeliver")
        unwrap_response(resp)
