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

import typing
from json.decoder import JSONDecodeError

from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.http_response import AsyncHttpResponse, HttpResponse
from ..core.jsonable_encoder import jsonable_encoder
from ..core.pagination import AsyncPager, BaseHttpResponse, SyncPager
from ..core.request_options import RequestOptions
from ..core.unchecked_base_model import construct_type
from ..types.get_merchant_response import GetMerchantResponse
from ..types.list_merchants_response import ListMerchantsResponse
from ..types.merchant import Merchant


class RawMerchantsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    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
        """
        _response = self._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(),
                    ),
                )
                _items = _parsed_response.merchant
                _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,
                )
                return SyncPager(
                    has_next=_has_next, items=_items, get_next=_get_next, response=BaseHttpResponse(response=_response)
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get(
        self, merchant_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[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
        -------
        HttpResponse[GetMerchantResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/merchants/{jsonable_encoder(merchant_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetMerchantResponse,
                    construct_type(
                        type_=GetMerchantResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


class AsyncRawMerchantsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    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
        """
        _response = await self._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(),
                    ),
                )
                _items = _parsed_response.merchant
                _parsed_next = _parsed_response.cursor
                _has_next = _parsed_next is not None and _parsed_next != ""

                async def _get_next():
                    return await self.list(
                        cursor=_parsed_next,
                        request_options=request_options,
                    )

                return AsyncPager(
                    has_next=_has_next, items=_items, get_next=_get_next, response=BaseHttpResponse(response=_response)
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get(
        self, merchant_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[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
        -------
        AsyncHttpResponse[GetMerchantResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/merchants/{jsonable_encoder(merchant_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetMerchantResponse,
                    construct_type(
                        type_=GetMerchantResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
