# This file was auto-generated by Fern from our API Definition.

from ..core.client_wrapper import SyncClientWrapper
from .raw_client import RawMerchantsClient
from .custom_attribute_definitions.client import CustomAttributeDefinitionsClient
from .custom_attributes.client import CustomAttributesClient
import typing
from ..core.request_options import RequestOptions
from ..core.pagination import SyncPager
from ..types.merchant import Merchant
from ..types.list_merchants_response import ListMerchantsResponse
from ..core.unchecked_base_model import construct_type
from json.decoder import JSONDecodeError
from ..core.api_error import ApiError
from ..types.get_merchant_response import GetMerchantResponse
from ..core.client_wrapper import AsyncClientWrapper
from .raw_client import AsyncRawMerchantsClient
from .custom_attribute_definitions.client import AsyncCustomAttributeDefinitionsClient
from .custom_attributes.client import AsyncCustomAttributesClient
from ..core.pagination import AsyncPager


class MerchantsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawMerchantsClient(client_wrapper=client_wrapper)
        self.custom_attribute_definitions = CustomAttributeDefinitionsClient(client_wrapper=client_wrapper)

        self.custom_attributes = CustomAttributesClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> RawMerchantsClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        RawMerchantsClient
        """
        return self._raw_client

    def list(
        self, *, cursor: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None
    ) -> SyncPager[Merchant]:
        """
        Provides details about the merchant associated with a given access token.

        The access token used to connect your application to a Square seller is associated
        with a single merchant. That means that `ListMerchants` returns a list
        with a single `Merchant` object. You can specify your personal access token
        to get your own merchant information or specify an OAuth token to get the
        information for the merchant that granted your application access.

        If you know the merchant ID, you can also use the [RetrieveMerchant](api-endpoint:Merchants-RetrieveMerchant)
        endpoint to retrieve the merchant information.

        Parameters
        ----------
        cursor : typing.Optional[int]
            The cursor generated by the previous response.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        SyncPager[Merchant]
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        response = client.merchants.list()
        for item in response:
            yield item
        # alternatively, you can paginate page-by-page
        for page in response.iter_pages():
            yield page
        """
        _response = self._raw_client._client_wrapper.httpx_client.request(
            "v2/merchants",
            method="GET",
            params={
                "cursor": cursor,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListMerchantsResponse,
                    construct_type(
                        type_=ListMerchantsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _parsed_next = _parsed_response.cursor
                _has_next = _parsed_next is not None and _parsed_next != ""
                _get_next = lambda: self.list(
                    cursor=_parsed_next,
                    request_options=request_options,
                )
                _items = _parsed_response.merchant
                return SyncPager(has_next=_has_next, items=_items, get_next=_get_next)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get(self, merchant_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetMerchantResponse:
        """
        Retrieves the `Merchant` object for the given `merchant_id`.

        Parameters
        ----------
        merchant_id : str
            The ID of the merchant to retrieve. If the string "me" is supplied as the ID,
            then retrieve the merchant that is currently accessible to this call.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        GetMerchantResponse
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        client.merchants.get(
            merchant_id="merchant_id",
        )
        """
        response = self._raw_client.get(merchant_id, request_options=request_options)
        return response.data


class AsyncMerchantsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawMerchantsClient(client_wrapper=client_wrapper)
        self.custom_attribute_definitions = AsyncCustomAttributeDefinitionsClient(client_wrapper=client_wrapper)

        self.custom_attributes = AsyncCustomAttributesClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> AsyncRawMerchantsClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        AsyncRawMerchantsClient
        """
        return self._raw_client

    async def list(
        self, *, cursor: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncPager[Merchant]:
        """
        Provides details about the merchant associated with a given access token.

        The access token used to connect your application to a Square seller is associated
        with a single merchant. That means that `ListMerchants` returns a list
        with a single `Merchant` object. You can specify your personal access token
        to get your own merchant information or specify an OAuth token to get the
        information for the merchant that granted your application access.

        If you know the merchant ID, you can also use the [RetrieveMerchant](api-endpoint:Merchants-RetrieveMerchant)
        endpoint to retrieve the merchant information.

        Parameters
        ----------
        cursor : typing.Optional[int]
            The cursor generated by the previous response.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncPager[Merchant]
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            response = await client.merchants.list()
            async for item in response:
                yield item
            # alternatively, you can paginate page-by-page
            async for page in response.iter_pages():
                yield page


        asyncio.run(main())
        """
        _response = await self._raw_client._client_wrapper.httpx_client.request(
            "v2/merchants",
            method="GET",
            params={
                "cursor": cursor,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListMerchantsResponse,
                    construct_type(
                        type_=ListMerchantsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _parsed_next = _parsed_response.cursor
                _has_next = _parsed_next is not None and _parsed_next != ""
                _get_next = lambda: self.list(
                    cursor=_parsed_next,
                    request_options=request_options,
                )
                _items = _parsed_response.merchant
                return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get(
        self, merchant_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> GetMerchantResponse:
        """
        Retrieves the `Merchant` object for the given `merchant_id`.

        Parameters
        ----------
        merchant_id : str
            The ID of the merchant to retrieve. If the string "me" is supplied as the ID,
            then retrieve the merchant that is currently accessible to this call.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        GetMerchantResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.merchants.get(
                merchant_id="merchant_id",
            )


        asyncio.run(main())
        """
        response = await self._raw_client.get(merchant_id, request_options=request_options)
        return response.data
