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

import typing
from ..core.client_wrapper import SyncClientWrapper
from ..requests.loyalty_event_query import LoyaltyEventQueryParams
from ..core.request_options import RequestOptions
from ..core.http_response import HttpResponse
from ..types.search_loyalty_events_response import SearchLoyaltyEventsResponse
from ..core.serialization import convert_and_respect_annotation_metadata
from ..core.unchecked_base_model import construct_type
from json.decoder import JSONDecodeError
from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper
from ..core.http_response import AsyncHttpResponse

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


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

    def search_events(
        self,
        *,
        query: typing.Optional[LoyaltyEventQueryParams] = OMIT,
        limit: typing.Optional[int] = OMIT,
        cursor: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[SearchLoyaltyEventsResponse]:
        """
        Searches for loyalty events.

        A Square loyalty program maintains a ledger of events that occur during the lifetime of a
        buyer's loyalty account. Each change in the point balance
        (for example, points earned, points redeemed, and points expired) is
        recorded in the ledger. Using this endpoint, you can search the ledger for events.

        Search results are sorted by `created_at` in descending order.

        Parameters
        ----------
        query : typing.Optional[LoyaltyEventQueryParams]
            A set of one or more predefined query filters to apply when
            searching for loyalty events. The endpoint performs a logical AND to
            evaluate multiple filters and performs a logical OR on arrays
            that specifies multiple field values.

        limit : typing.Optional[int]
            The maximum number of results to include in the response.
            The last page might contain fewer events.
            The default is 30 events.

        cursor : typing.Optional[str]
            A pagination cursor returned by a previous call to this endpoint.
            Provide this to retrieve the next set of results for your original query.
            For more information, see [Pagination](https://developer.squareup.com/docs/build-basics/common-api-patterns/pagination).

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

        Returns
        -------
        HttpResponse[SearchLoyaltyEventsResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/loyalty/events/search",
            method="POST",
            json={
                "query": convert_and_respect_annotation_metadata(
                    object_=query, annotation=LoyaltyEventQueryParams, direction="write"
                ),
                "limit": limit,
                "cursor": cursor,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SearchLoyaltyEventsResponse,
                    construct_type(
                        type_=SearchLoyaltyEventsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _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 AsyncRawLoyaltyClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def search_events(
        self,
        *,
        query: typing.Optional[LoyaltyEventQueryParams] = OMIT,
        limit: typing.Optional[int] = OMIT,
        cursor: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[SearchLoyaltyEventsResponse]:
        """
        Searches for loyalty events.

        A Square loyalty program maintains a ledger of events that occur during the lifetime of a
        buyer's loyalty account. Each change in the point balance
        (for example, points earned, points redeemed, and points expired) is
        recorded in the ledger. Using this endpoint, you can search the ledger for events.

        Search results are sorted by `created_at` in descending order.

        Parameters
        ----------
        query : typing.Optional[LoyaltyEventQueryParams]
            A set of one or more predefined query filters to apply when
            searching for loyalty events. The endpoint performs a logical AND to
            evaluate multiple filters and performs a logical OR on arrays
            that specifies multiple field values.

        limit : typing.Optional[int]
            The maximum number of results to include in the response.
            The last page might contain fewer events.
            The default is 30 events.

        cursor : typing.Optional[str]
            A pagination cursor returned by a previous call to this endpoint.
            Provide this to retrieve the next set of results for your original query.
            For more information, see [Pagination](https://developer.squareup.com/docs/build-basics/common-api-patterns/pagination).

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

        Returns
        -------
        AsyncHttpResponse[SearchLoyaltyEventsResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/loyalty/events/search",
            method="POST",
            json={
                "query": convert_and_respect_annotation_metadata(
                    object_=query, annotation=LoyaltyEventQueryParams, direction="write"
                ),
                "limit": limit,
                "cursor": cursor,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SearchLoyaltyEventsResponse,
                    construct_type(
                        type_=SearchLoyaltyEventsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _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)
