# 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_payout_response import GetPayoutResponse
from ..types.list_payout_entries_response import ListPayoutEntriesResponse
from ..types.list_payouts_response import ListPayoutsResponse
from ..types.payout import Payout
from ..types.payout_entry import PayoutEntry
from ..types.payout_status import PayoutStatus
from ..types.sort_order import SortOrder


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

    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
        """
        _response = self._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(),
                    ),
                )
                _items = _parsed_response.payouts
                _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,
                )
                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, payout_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[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
        -------
        HttpResponse[GetPayoutResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/payouts/{jsonable_encoder(payout_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetPayoutResponse,
                    construct_type(
                        type_=GetPayoutResponse,  # 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)

    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
        """
        _response = self._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(),
                    ),
                )
                _items = _parsed_response.payout_entries
                _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,
                )
                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)


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

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

                async def _get_next():
                    return await 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,
                    )

                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, payout_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[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
        -------
        AsyncHttpResponse[GetPayoutResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/payouts/{jsonable_encoder(payout_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetPayoutResponse,
                    construct_type(
                        type_=GetPayoutResponse,  # 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)

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

                async def _get_next():
                    return await self.list_entries(
                        payout_id,
                        sort_order=sort_order,
                        cursor=_parsed_next,
                        limit=limit,
                        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)
