import abc
from typing import Optional, Any

from ._base import NotchPayBaseResource, AsyncNotchPayBaseResource
from .schemas.base import NotchPayResponseList, MaybeAwaitable
from .schemas.channels import NotchPayChannel

__all__ = ["NotchPayChannels", "AsyncNotchPayChannels", ]


class _NotchPayChannels(abc.ABC):

    @abc.abstractmethod
    def list(
            self,
            country: Optional[str] = None,
            amount: Optional[int] = None,
            currency: str = "XAF"
    ) -> MaybeAwaitable[NotchPayResponseList[NotchPayChannel]]:
        """
        List available payment channels.

        Args:
            country: Country code to filter channels (e.g., "CM")
            amount: Minimum amount to filter channels
            currency: Currency code for minimum amount (default: "XAF")

        Returns:
            Response containing available payment channels

        References:
            https://developer.notchpay.co/api-reference/list-all-payment-channels

        Examples:
            >>> from notchpay import NotchPay
            >>> notchpay = NotchPay("your_api_key")
            >>> channels = notchpay.channels.list(country="CM", amount=1000)
            >>> for channel in channels.items:
            ...     print(channel.name)
        """
        # TODO: Filters by amount not working yet on api
        ...

    def _build_list_params(
            self,
            country: Optional[str] = None,
            amount: Optional[int] = None,
            currency: str = "XAF"
    ) -> dict[str, Any]:
        params: dict[str, Any] = {}
        if country is not None:
            params["country"] = country
        if amount is not None:
            params["amount"] = amount
        if currency != "XAF":
            params["currency"] = currency

        return {'params': params}


class NotchPayChannels(_NotchPayChannels, NotchPayBaseResource):

    def list(
            self,
            country: Optional[str] = None,
            amount: Optional[int] = None,
            currency: str = "XAF"
    ) -> NotchPayResponseList[NotchPayChannel]:
        params = super()._build_list_params(country, amount, currency)
        return self._request("GET", "/channels", response_model=NotchPayResponseList[NotchPayChannel], **params)


class AsyncNotchPayChannels(_NotchPayChannels, AsyncNotchPayBaseResource):

    async def list(
            self,
            country: Optional[str] = None,
            amount: Optional[int] = None,
            currency: str = "XAF"
    ) -> NotchPayResponseList[NotchPayChannel]:
        params = super()._build_list_params(country, amount, currency)
        return await self._request("GET", "/channels", response_model=NotchPayResponseList[NotchPayChannel], **params)
