from __future__ import annotations

from typing import TYPE_CHECKING
from urllib.parse import quote

from .._base_client import RequestOptions
from .._pagination import AsyncPage, SyncPage

if TYPE_CHECKING:
    from .._client import AsyncShipMail, ShipMail
    from .._types.common import MethodOptions, PaginatedResponse
    from .._types.mailbox import (
        CreateMailboxParams,
        ListMailboxesParams,
        Mailbox,
        UpdateAutoReplyParams,
        UpdateMailboxParams,
    )


class SyncMailboxes:
    def __init__(self, client: ShipMail) -> None:
        self._client = client

    def create(self, params: CreateMailboxParams, options: MethodOptions | None = None) -> Mailbox:
        return self._client.request(RequestOptions(method="POST", path="/mailboxes", body=params, method_options=options))

    def list(self, params: ListMailboxesParams | None = None, options: MethodOptions | None = None) -> PaginatedResponse:
        return self._client.request(RequestOptions(
            method="GET",
            path="/mailboxes",
            query={
                "domain_id": params.get("domain_id") if params else None,
                "cursor": params.get("cursor") if params else None,
                "limit": params.get("limit") if params else None,
            },
            method_options=options,
        ))

    def list_auto_paginating(self, *, domain_id: str | None = None, limit: int | None = None) -> SyncPage[Mailbox]:
        return SyncPage(self._client, "/mailboxes", {"domain_id": domain_id, "limit": limit})

    def get(self, id: str, options: MethodOptions | None = None) -> Mailbox:
        return self._client.request(RequestOptions(method="GET", path=f"/mailboxes/{quote(id, safe='')}", method_options=options))

    def update(self, id: str, params: UpdateMailboxParams, options: MethodOptions | None = None) -> Mailbox:
        return self._client.request(RequestOptions(method="PATCH", path=f"/mailboxes/{quote(id, safe='')}", body=params, method_options=options))

    def delete(self, id: str, options: MethodOptions | None = None) -> None:
        self._client.request(RequestOptions(method="DELETE", path=f"/mailboxes/{quote(id, safe='')}", method_options=options))

    def update_auto_reply(self, id: str, params: UpdateAutoReplyParams, options: MethodOptions | None = None) -> Mailbox:
        return self._client.request(RequestOptions(method="PATCH", path=f"/mailboxes/{quote(id, safe='')}/auto-reply", body=params, method_options=options))


class AsyncMailboxes:
    def __init__(self, client: AsyncShipMail) -> None:
        self._client = client

    async def create(self, params: CreateMailboxParams, options: MethodOptions | None = None) -> Mailbox:
        return await self._client.request(RequestOptions(method="POST", path="/mailboxes", body=params, method_options=options))

    async def list(self, params: ListMailboxesParams | None = None, options: MethodOptions | None = None) -> PaginatedResponse:
        return await self._client.request(RequestOptions(
            method="GET",
            path="/mailboxes",
            query={
                "domain_id": params.get("domain_id") if params else None,
                "cursor": params.get("cursor") if params else None,
                "limit": params.get("limit") if params else None,
            },
            method_options=options,
        ))

    def list_auto_paginating(self, *, domain_id: str | None = None, limit: int | None = None) -> AsyncPage[Mailbox]:
        return AsyncPage(self._client, "/mailboxes", {"domain_id": domain_id, "limit": limit})

    async def get(self, id: str, options: MethodOptions | None = None) -> Mailbox:
        return await self._client.request(RequestOptions(method="GET", path=f"/mailboxes/{quote(id, safe='')}", method_options=options))

    async def update(self, id: str, params: UpdateMailboxParams, options: MethodOptions | None = None) -> Mailbox:
        return await self._client.request(RequestOptions(method="PATCH", path=f"/mailboxes/{quote(id, safe='')}", body=params, method_options=options))

    async def delete(self, id: str, options: MethodOptions | None = None) -> None:
        await self._client.request(RequestOptions(method="DELETE", path=f"/mailboxes/{quote(id, safe='')}", method_options=options))

    async def update_auto_reply(self, id: str, params: UpdateAutoReplyParams, options: MethodOptions | None = None) -> Mailbox:
        return await self._client.request(RequestOptions(method="PATCH", path=f"/mailboxes/{quote(id, safe='')}/auto-reply", body=params, method_options=options))
