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

import typing
from ...core.client_wrapper import SyncClientWrapper
from .raw_client import RawRewardsClient
from ...requests.loyalty_reward import LoyaltyRewardParams
from ...core.request_options import RequestOptions
from ...types.create_loyalty_reward_response import CreateLoyaltyRewardResponse
from ...requests.search_loyalty_rewards_request_loyalty_reward_query import (
    SearchLoyaltyRewardsRequestLoyaltyRewardQueryParams,
)
from ...types.search_loyalty_rewards_response import SearchLoyaltyRewardsResponse
from ...types.get_loyalty_reward_response import GetLoyaltyRewardResponse
from ...types.delete_loyalty_reward_response import DeleteLoyaltyRewardResponse
from ...types.redeem_loyalty_reward_response import RedeemLoyaltyRewardResponse
from ...core.client_wrapper import AsyncClientWrapper
from .raw_client import AsyncRawRewardsClient

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


class RewardsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawRewardsClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        RawRewardsClient
        """
        return self._raw_client

    def create(
        self,
        *,
        reward: LoyaltyRewardParams,
        idempotency_key: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateLoyaltyRewardResponse:
        """
        Creates a loyalty reward. In the process, the endpoint does following:

        - Uses the `reward_tier_id` in the request to determine the number of points
        to lock for this reward.
        - If the request includes `order_id`, it adds the reward and related discount to the order.

        After a reward is created, the points are locked and
        not available for the buyer to redeem another reward.

        Parameters
        ----------
        reward : LoyaltyRewardParams
            The reward to create.

        idempotency_key : str
            A unique string that identifies this `CreateLoyaltyReward` request.
            Keys can be any valid string, but must be unique for every request.

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

        Returns
        -------
        CreateLoyaltyRewardResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.loyalty.rewards.create(
            reward={
                "loyalty_account_id": "5adcb100-07f1-4ee7-b8c6-6bb9ebc474bd",
                "reward_tier_id": "e1b39225-9da5-43d1-a5db-782cdd8ad94f",
                "order_id": "RFZfrdtm3mhO1oGzf5Cx7fEMsmGZY",
            },
            idempotency_key="18c2e5ea-a620-4b1f-ad60-7b167285e451",
        )
        """
        response = self._raw_client.create(
            reward=reward, idempotency_key=idempotency_key, request_options=request_options
        )
        return response.data

    def search(
        self,
        *,
        query: typing.Optional[SearchLoyaltyRewardsRequestLoyaltyRewardQueryParams] = OMIT,
        limit: typing.Optional[int] = OMIT,
        cursor: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SearchLoyaltyRewardsResponse:
        """
        Searches for loyalty rewards. This endpoint accepts a request with no query filters and returns results for all loyalty accounts.
        If you include a `query` object, `loyalty_account_id` is required and `status` is  optional.

        If you know a reward ID, use the
        [RetrieveLoyaltyReward](api-endpoint:Loyalty-RetrieveLoyaltyReward) endpoint.

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

        Parameters
        ----------
        query : typing.Optional[SearchLoyaltyRewardsRequestLoyaltyRewardQueryParams]
            The search criteria for the request.
            If empty, the endpoint retrieves all loyalty rewards in the loyalty program.

        limit : typing.Optional[int]
            The maximum number of results to return in the response. The default value is 30.

        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 the 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
        -------
        SearchLoyaltyRewardsResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.loyalty.rewards.search(
            query={"loyalty_account_id": "5adcb100-07f1-4ee7-b8c6-6bb9ebc474bd"},
            limit=10,
        )
        """
        response = self._raw_client.search(query=query, limit=limit, cursor=cursor, request_options=request_options)
        return response.data

    def get(
        self, reward_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> GetLoyaltyRewardResponse:
        """
        Retrieves a loyalty reward.

        Parameters
        ----------
        reward_id : str
            The ID of the [loyalty reward](entity:LoyaltyReward) to retrieve.

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

        Returns
        -------
        GetLoyaltyRewardResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.loyalty.rewards.get(
            reward_id="reward_id",
        )
        """
        response = self._raw_client.get(reward_id, request_options=request_options)
        return response.data

    def delete(
        self, reward_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> DeleteLoyaltyRewardResponse:
        """
        Deletes a loyalty reward by doing the following:

        - Returns the loyalty points back to the loyalty account.
        - If an order ID was specified when the reward was created
        (see [CreateLoyaltyReward](api-endpoint:Loyalty-CreateLoyaltyReward)),
        it updates the order by removing the reward and related
        discounts.

        You cannot delete a reward that has reached the terminal state (REDEEMED).

        Parameters
        ----------
        reward_id : str
            The ID of the [loyalty reward](entity:LoyaltyReward) to delete.

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

        Returns
        -------
        DeleteLoyaltyRewardResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.loyalty.rewards.delete(
            reward_id="reward_id",
        )
        """
        response = self._raw_client.delete(reward_id, request_options=request_options)
        return response.data

    def redeem(
        self,
        reward_id: str,
        *,
        idempotency_key: str,
        location_id: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> RedeemLoyaltyRewardResponse:
        """
        Redeems a loyalty reward.

        The endpoint sets the reward to the `REDEEMED` terminal state.

        If you are using your own order processing system (not using the
        Orders API), you call this endpoint after the buyer paid for the
        purchase.

        After the reward reaches the terminal state, it cannot be deleted.
        In other words, points used for the reward cannot be returned
        to the account.

        Parameters
        ----------
        reward_id : str
            The ID of the [loyalty reward](entity:LoyaltyReward) to redeem.

        idempotency_key : str
            A unique string that identifies this `RedeemLoyaltyReward` request.
            Keys can be any valid string, but must be unique for every request.

        location_id : str
            The ID of the [location](entity:Location) where the reward is redeemed.

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

        Returns
        -------
        RedeemLoyaltyRewardResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.loyalty.rewards.redeem(
            reward_id="reward_id",
            idempotency_key="98adc7f7-6963-473b-b29c-f3c9cdd7d994",
            location_id="P034NEENMD09F",
        )
        """
        response = self._raw_client.redeem(
            reward_id, idempotency_key=idempotency_key, location_id=location_id, request_options=request_options
        )
        return response.data


class AsyncRewardsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawRewardsClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        AsyncRawRewardsClient
        """
        return self._raw_client

    async def create(
        self,
        *,
        reward: LoyaltyRewardParams,
        idempotency_key: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateLoyaltyRewardResponse:
        """
        Creates a loyalty reward. In the process, the endpoint does following:

        - Uses the `reward_tier_id` in the request to determine the number of points
        to lock for this reward.
        - If the request includes `order_id`, it adds the reward and related discount to the order.

        After a reward is created, the points are locked and
        not available for the buyer to redeem another reward.

        Parameters
        ----------
        reward : LoyaltyRewardParams
            The reward to create.

        idempotency_key : str
            A unique string that identifies this `CreateLoyaltyReward` request.
            Keys can be any valid string, but must be unique for every request.

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

        Returns
        -------
        CreateLoyaltyRewardResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.loyalty.rewards.create(
                reward={
                    "loyalty_account_id": "5adcb100-07f1-4ee7-b8c6-6bb9ebc474bd",
                    "reward_tier_id": "e1b39225-9da5-43d1-a5db-782cdd8ad94f",
                    "order_id": "RFZfrdtm3mhO1oGzf5Cx7fEMsmGZY",
                },
                idempotency_key="18c2e5ea-a620-4b1f-ad60-7b167285e451",
            )


        asyncio.run(main())
        """
        response = await self._raw_client.create(
            reward=reward, idempotency_key=idempotency_key, request_options=request_options
        )
        return response.data

    async def search(
        self,
        *,
        query: typing.Optional[SearchLoyaltyRewardsRequestLoyaltyRewardQueryParams] = OMIT,
        limit: typing.Optional[int] = OMIT,
        cursor: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SearchLoyaltyRewardsResponse:
        """
        Searches for loyalty rewards. This endpoint accepts a request with no query filters and returns results for all loyalty accounts.
        If you include a `query` object, `loyalty_account_id` is required and `status` is  optional.

        If you know a reward ID, use the
        [RetrieveLoyaltyReward](api-endpoint:Loyalty-RetrieveLoyaltyReward) endpoint.

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

        Parameters
        ----------
        query : typing.Optional[SearchLoyaltyRewardsRequestLoyaltyRewardQueryParams]
            The search criteria for the request.
            If empty, the endpoint retrieves all loyalty rewards in the loyalty program.

        limit : typing.Optional[int]
            The maximum number of results to return in the response. The default value is 30.

        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 the 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
        -------
        SearchLoyaltyRewardsResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.loyalty.rewards.search(
                query={"loyalty_account_id": "5adcb100-07f1-4ee7-b8c6-6bb9ebc474bd"},
                limit=10,
            )


        asyncio.run(main())
        """
        response = await self._raw_client.search(
            query=query, limit=limit, cursor=cursor, request_options=request_options
        )
        return response.data

    async def get(
        self, reward_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> GetLoyaltyRewardResponse:
        """
        Retrieves a loyalty reward.

        Parameters
        ----------
        reward_id : str
            The ID of the [loyalty reward](entity:LoyaltyReward) to retrieve.

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

        Returns
        -------
        GetLoyaltyRewardResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.loyalty.rewards.get(
                reward_id="reward_id",
            )


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

    async def delete(
        self, reward_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> DeleteLoyaltyRewardResponse:
        """
        Deletes a loyalty reward by doing the following:

        - Returns the loyalty points back to the loyalty account.
        - If an order ID was specified when the reward was created
        (see [CreateLoyaltyReward](api-endpoint:Loyalty-CreateLoyaltyReward)),
        it updates the order by removing the reward and related
        discounts.

        You cannot delete a reward that has reached the terminal state (REDEEMED).

        Parameters
        ----------
        reward_id : str
            The ID of the [loyalty reward](entity:LoyaltyReward) to delete.

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

        Returns
        -------
        DeleteLoyaltyRewardResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.loyalty.rewards.delete(
                reward_id="reward_id",
            )


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

    async def redeem(
        self,
        reward_id: str,
        *,
        idempotency_key: str,
        location_id: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> RedeemLoyaltyRewardResponse:
        """
        Redeems a loyalty reward.

        The endpoint sets the reward to the `REDEEMED` terminal state.

        If you are using your own order processing system (not using the
        Orders API), you call this endpoint after the buyer paid for the
        purchase.

        After the reward reaches the terminal state, it cannot be deleted.
        In other words, points used for the reward cannot be returned
        to the account.

        Parameters
        ----------
        reward_id : str
            The ID of the [loyalty reward](entity:LoyaltyReward) to redeem.

        idempotency_key : str
            A unique string that identifies this `RedeemLoyaltyReward` request.
            Keys can be any valid string, but must be unique for every request.

        location_id : str
            The ID of the [location](entity:Location) where the reward is redeemed.

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

        Returns
        -------
        RedeemLoyaltyRewardResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.loyalty.rewards.redeem(
                reward_id="reward_id",
                idempotency_key="98adc7f7-6963-473b-b29c-f3c9cdd7d994",
                location_id="P034NEENMD09F",
            )


        asyncio.run(main())
        """
        response = await self._raw_client.redeem(
            reward_id, idempotency_key=idempotency_key, location_id=location_id, request_options=request_options
        )
        return response.data
