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

from ..core.client_wrapper import SyncClientWrapper
from .raw_client import RawPayoutsClient
import typing
from ..types.payout_status import PayoutStatus
from ..types.sort_order import SortOrder
from ..core.request_options import RequestOptions
from ..core.pagination import SyncPager
from ..types.payout import Payout
from ..types.list_payouts_response import ListPayoutsResponse
from ..core.unchecked_base_model import construct_type
from json.decoder import JSONDecodeError
from ..core.api_error import ApiError
from ..types.get_payout_response import GetPayoutResponse
from ..types.payout_entry import PayoutEntry
from ..core.jsonable_encoder import jsonable_encoder
from ..types.list_payout_entries_response import ListPayoutEntriesResponse
from ..core.client_wrapper import AsyncClientWrapper
from .raw_client import AsyncRawPayoutsClient
from ..core.pagination import AsyncPager


class PayoutsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawPayoutsClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        RawPayoutsClient
        """
        return self._raw_client

    def list(
        self,
        *,
        location_id: typing.Optional[str] = None,
        status: typing.Optional[PayoutStatus] = None,
        begin_time: typing.Optional[str] = None,
        end_time: typing.Optional[str] = None,
        sort_order: typing.Optional[SortOrder] = None,
        cursor: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[Payout]:
        """
        Retrieves a list of all payouts for the default location.
        You can filter payouts by location ID, status, time range, and order them in ascending or descending order.
        To call this endpoint, set `PAYOUTS_READ` for the OAuth scope.

        Parameters
        ----------
        location_id : typing.Optional[str]
            The ID of the location for which to list the payouts.
            By default, payouts are returned for the default (main) location associated with the seller.

        status : typing.Optional[PayoutStatus]
            If provided, only payouts with the given status are returned.

        begin_time : typing.Optional[str]
            The timestamp for the beginning of the payout creation time, in RFC 3339 format.
            Inclusive. Default: The current time minus one year.

        end_time : typing.Optional[str]
            The timestamp for the end of the payout creation time, in RFC 3339 format.
            Default: The current time.

        sort_order : typing.Optional[SortOrder]
            The order in which payouts are listed.

        cursor : typing.Optional[str]
            A pagination cursor returned by a previous call to this endpoint.
            Provide this cursor to retrieve the next set of results for the original query.
            For more information, see [Pagination](https://developer.squareup.com/docs/build-basics/common-api-patterns/pagination).
            If request parameters change between requests, subsequent results may contain duplicates or missing records.

        limit : typing.Optional[int]
            The maximum number of results to be returned in a single page.
            It is possible to receive fewer results than the specified limit on a given page.
            The default value of 100 is also the maximum allowed value. If the provided value is
            greater than 100, it is ignored and the default value is used instead.
            Default: `100`

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

        Returns
        -------
        SyncPager[Payout]
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        response = client.payouts.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/payouts",
            method="GET",
            params={
                "location_id": location_id,
                "status": status,
                "begin_time": begin_time,
                "end_time": end_time,
                "sort_order": sort_order,
                "cursor": cursor,
                "limit": limit,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListPayoutsResponse,
                    construct_type(
                        type_=ListPayoutsResponse,  # 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(
                    location_id=location_id,
                    status=status,
                    begin_time=begin_time,
                    end_time=end_time,
                    sort_order=sort_order,
                    cursor=_parsed_next,
                    limit=limit,
                    request_options=request_options,
                )
                _items = _parsed_response.payouts
                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, payout_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetPayoutResponse:
        """
        Retrieves details of a specific payout identified by a payout ID.
        To call this endpoint, set `PAYOUTS_READ` for the OAuth scope.

        Parameters
        ----------
        payout_id : str
            The ID of the payout to retrieve the information for.

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

        Returns
        -------
        GetPayoutResponse
            Success

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

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

    def list_entries(
        self,
        payout_id: str,
        *,
        sort_order: typing.Optional[SortOrder] = None,
        cursor: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[PayoutEntry]:
        """
        Retrieves a list of all payout entries for a specific payout.
        To call this endpoint, set `PAYOUTS_READ` for the OAuth scope.

        Parameters
        ----------
        payout_id : str
            The ID of the payout to retrieve the information for.

        sort_order : typing.Optional[SortOrder]
            The order in which payout entries are listed.

        cursor : typing.Optional[str]
            A pagination cursor returned by a previous call to this endpoint.
            Provide this cursor to retrieve the next set of results for the original query.
            For more information, see [Pagination](https://developer.squareup.com/docs/build-basics/common-api-patterns/pagination).
            If request parameters change between requests, subsequent results may contain duplicates or missing records.

        limit : typing.Optional[int]
            The maximum number of results to be returned in a single page.
            It is possible to receive fewer results than the specified limit on a given page.
            The default value of 100 is also the maximum allowed value. If the provided value is
            greater than 100, it is ignored and the default value is used instead.
            Default: `100`

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

        Returns
        -------
        SyncPager[PayoutEntry]
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        response = client.payouts.list_entries(
            payout_id="payout_id",
        )
        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(
            f"v2/payouts/{jsonable_encoder(payout_id)}/payout-entries",
            method="GET",
            params={
                "sort_order": sort_order,
                "cursor": cursor,
                "limit": limit,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListPayoutEntriesResponse,
                    construct_type(
                        type_=ListPayoutEntriesResponse,  # 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_entries(
                    payout_id,
                    sort_order=sort_order,
                    cursor=_parsed_next,
                    limit=limit,
                    request_options=request_options,
                )
                _items = _parsed_response.payout_entries
                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)


class AsyncPayoutsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawPayoutsClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        AsyncRawPayoutsClient
        """
        return self._raw_client

    async def list(
        self,
        *,
        location_id: typing.Optional[str] = None,
        status: typing.Optional[PayoutStatus] = None,
        begin_time: typing.Optional[str] = None,
        end_time: typing.Optional[str] = None,
        sort_order: typing.Optional[SortOrder] = None,
        cursor: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[Payout]:
        """
        Retrieves a list of all payouts for the default location.
        You can filter payouts by location ID, status, time range, and order them in ascending or descending order.
        To call this endpoint, set `PAYOUTS_READ` for the OAuth scope.

        Parameters
        ----------
        location_id : typing.Optional[str]
            The ID of the location for which to list the payouts.
            By default, payouts are returned for the default (main) location associated with the seller.

        status : typing.Optional[PayoutStatus]
            If provided, only payouts with the given status are returned.

        begin_time : typing.Optional[str]
            The timestamp for the beginning of the payout creation time, in RFC 3339 format.
            Inclusive. Default: The current time minus one year.

        end_time : typing.Optional[str]
            The timestamp for the end of the payout creation time, in RFC 3339 format.
            Default: The current time.

        sort_order : typing.Optional[SortOrder]
            The order in which payouts are listed.

        cursor : typing.Optional[str]
            A pagination cursor returned by a previous call to this endpoint.
            Provide this cursor to retrieve the next set of results for the original query.
            For more information, see [Pagination](https://developer.squareup.com/docs/build-basics/common-api-patterns/pagination).
            If request parameters change between requests, subsequent results may contain duplicates or missing records.

        limit : typing.Optional[int]
            The maximum number of results to be returned in a single page.
            It is possible to receive fewer results than the specified limit on a given page.
            The default value of 100 is also the maximum allowed value. If the provided value is
            greater than 100, it is ignored and the default value is used instead.
            Default: `100`

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

        Returns
        -------
        AsyncPager[Payout]
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            response = await client.payouts.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/payouts",
            method="GET",
            params={
                "location_id": location_id,
                "status": status,
                "begin_time": begin_time,
                "end_time": end_time,
                "sort_order": sort_order,
                "cursor": cursor,
                "limit": limit,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListPayoutsResponse,
                    construct_type(
                        type_=ListPayoutsResponse,  # 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(
                    location_id=location_id,
                    status=status,
                    begin_time=begin_time,
                    end_time=end_time,
                    sort_order=sort_order,
                    cursor=_parsed_next,
                    limit=limit,
                    request_options=request_options,
                )
                _items = _parsed_response.payouts
                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, payout_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> GetPayoutResponse:
        """
        Retrieves details of a specific payout identified by a payout ID.
        To call this endpoint, set `PAYOUTS_READ` for the OAuth scope.

        Parameters
        ----------
        payout_id : str
            The ID of the payout to retrieve the information for.

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

        Returns
        -------
        GetPayoutResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


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


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

    async def list_entries(
        self,
        payout_id: str,
        *,
        sort_order: typing.Optional[SortOrder] = None,
        cursor: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[PayoutEntry]:
        """
        Retrieves a list of all payout entries for a specific payout.
        To call this endpoint, set `PAYOUTS_READ` for the OAuth scope.

        Parameters
        ----------
        payout_id : str
            The ID of the payout to retrieve the information for.

        sort_order : typing.Optional[SortOrder]
            The order in which payout entries are listed.

        cursor : typing.Optional[str]
            A pagination cursor returned by a previous call to this endpoint.
            Provide this cursor to retrieve the next set of results for the original query.
            For more information, see [Pagination](https://developer.squareup.com/docs/build-basics/common-api-patterns/pagination).
            If request parameters change between requests, subsequent results may contain duplicates or missing records.

        limit : typing.Optional[int]
            The maximum number of results to be returned in a single page.
            It is possible to receive fewer results than the specified limit on a given page.
            The default value of 100 is also the maximum allowed value. If the provided value is
            greater than 100, it is ignored and the default value is used instead.
            Default: `100`

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

        Returns
        -------
        AsyncPager[PayoutEntry]
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            response = await client.payouts.list_entries(
                payout_id="payout_id",
            )
            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(
            f"v2/payouts/{jsonable_encoder(payout_id)}/payout-entries",
            method="GET",
            params={
                "sort_order": sort_order,
                "cursor": cursor,
                "limit": limit,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListPayoutEntriesResponse,
                    construct_type(
                        type_=ListPayoutEntriesResponse,  # 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_entries(
                    payout_id,
                    sort_order=sort_order,
                    cursor=_parsed_next,
                    limit=limit,
                    request_options=request_options,
                )
                _items = _parsed_response.payout_entries
                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)
