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

import typing
from ...core.client_wrapper import SyncClientWrapper
from .raw_client import RawProgramsClient
from .promotions.client import PromotionsClient
from ...core.request_options import RequestOptions
from ...types.list_loyalty_programs_response import ListLoyaltyProgramsResponse
from ...types.get_loyalty_program_response import GetLoyaltyProgramResponse
from ...requests.money import MoneyParams
from ...types.calculate_loyalty_points_response import CalculateLoyaltyPointsResponse
from ...core.client_wrapper import AsyncClientWrapper
from .raw_client import AsyncRawProgramsClient
from .promotions.client import AsyncPromotionsClient

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


class ProgramsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawProgramsClient(client_wrapper=client_wrapper)
        self.promotions = PromotionsClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        RawProgramsClient
        """
        return self._raw_client

    def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> ListLoyaltyProgramsResponse:
        """
        Returns a list of loyalty programs in the seller's account.
        Loyalty programs define how buyers can earn points and redeem points for rewards. Square sellers can have only one loyalty program, which is created and managed from the Seller Dashboard. For more information, see [Loyalty Program Overview](https://developer.squareup.com/docs/loyalty/overview).


        Replaced with [RetrieveLoyaltyProgram](api-endpoint:Loyalty-RetrieveLoyaltyProgram) when used with the keyword `main`.

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

        Returns
        -------
        ListLoyaltyProgramsResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.loyalty.programs.list()
        """
        response = self._raw_client.list(request_options=request_options)
        return response.data

    def get(
        self, program_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> GetLoyaltyProgramResponse:
        """
        Retrieves the loyalty program in a seller's account, specified by the program ID or the keyword `main`.

        Loyalty programs define how buyers can earn points and redeem points for rewards. Square sellers can have only one loyalty program, which is created and managed from the Seller Dashboard. For more information, see [Loyalty Program Overview](https://developer.squareup.com/docs/loyalty/overview).

        Parameters
        ----------
        program_id : str
            The ID of the loyalty program or the keyword `main`. Either value can be used to retrieve the single loyalty program that belongs to the seller.

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

        Returns
        -------
        GetLoyaltyProgramResponse
            Success

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

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

    def calculate(
        self,
        program_id: str,
        *,
        order_id: typing.Optional[str] = OMIT,
        transaction_amount_money: typing.Optional[MoneyParams] = OMIT,
        loyalty_account_id: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CalculateLoyaltyPointsResponse:
        """
        Calculates the number of points a buyer can earn from a purchase. Applications might call this endpoint
        to display the points to the buyer.

        - If you are using the Orders API to manage orders, provide the `order_id` and (optional) `loyalty_account_id`.
        Square reads the order to compute the points earned from the base loyalty program and an associated
        [loyalty promotion](entity:LoyaltyPromotion).

        - If you are not using the Orders API to manage orders, provide `transaction_amount_money` with the
        purchase amount. Square uses this amount to calculate the points earned from the base loyalty program,
        but not points earned from a loyalty promotion. For spend-based and visit-based programs, the `tax_mode`
        setting of the accrual rule indicates how taxes should be treated for loyalty points accrual.
        If the purchase qualifies for program points, call
        [ListLoyaltyPromotions](api-endpoint:Loyalty-ListLoyaltyPromotions) and perform a client-side computation
        to calculate whether the purchase also qualifies for promotion points. For more information, see
        [Calculating promotion points](https://developer.squareup.com/docs/loyalty-api/loyalty-promotions#calculate-promotion-points).

        Parameters
        ----------
        program_id : str
            The ID of the [loyalty program](entity:LoyaltyProgram), which defines the rules for accruing points.

        order_id : typing.Optional[str]
            The [order](entity:Order) ID for which to calculate the points.
            Specify this field if your application uses the Orders API to process orders.
            Otherwise, specify the `transaction_amount_money`.

        transaction_amount_money : typing.Optional[MoneyParams]
            The purchase amount for which to calculate the points.
            Specify this field if your application does not use the Orders API to process orders.
            Otherwise, specify the `order_id`.

        loyalty_account_id : typing.Optional[str]
            The ID of the target [loyalty account](entity:LoyaltyAccount). Optionally specify this field
            if your application uses the Orders API to process orders.

            If specified, the `promotion_points` field in the response shows the number of points the buyer would
            earn from the purchase. In this case, Square uses the account ID to determine whether the promotion's
            `trigger_limit` (the maximum number of times that a buyer can trigger the promotion) has been reached.
            If not specified, the `promotion_points` field shows the number of points the purchase qualifies
            for regardless of the trigger limit.

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

        Returns
        -------
        CalculateLoyaltyPointsResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.loyalty.programs.calculate(
            program_id="program_id",
            order_id="RFZfrdtm3mhO1oGzf5Cx7fEMsmGZY",
            loyalty_account_id="79b807d2-d786-46a9-933b-918028d7a8c5",
        )
        """
        response = self._raw_client.calculate(
            program_id,
            order_id=order_id,
            transaction_amount_money=transaction_amount_money,
            loyalty_account_id=loyalty_account_id,
            request_options=request_options,
        )
        return response.data


class AsyncProgramsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawProgramsClient(client_wrapper=client_wrapper)
        self.promotions = AsyncPromotionsClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        AsyncRawProgramsClient
        """
        return self._raw_client

    async def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> ListLoyaltyProgramsResponse:
        """
        Returns a list of loyalty programs in the seller's account.
        Loyalty programs define how buyers can earn points and redeem points for rewards. Square sellers can have only one loyalty program, which is created and managed from the Seller Dashboard. For more information, see [Loyalty Program Overview](https://developer.squareup.com/docs/loyalty/overview).


        Replaced with [RetrieveLoyaltyProgram](api-endpoint:Loyalty-RetrieveLoyaltyProgram) when used with the keyword `main`.

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

        Returns
        -------
        ListLoyaltyProgramsResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.loyalty.programs.list()


        asyncio.run(main())
        """
        response = await self._raw_client.list(request_options=request_options)
        return response.data

    async def get(
        self, program_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> GetLoyaltyProgramResponse:
        """
        Retrieves the loyalty program in a seller's account, specified by the program ID or the keyword `main`.

        Loyalty programs define how buyers can earn points and redeem points for rewards. Square sellers can have only one loyalty program, which is created and managed from the Seller Dashboard. For more information, see [Loyalty Program Overview](https://developer.squareup.com/docs/loyalty/overview).

        Parameters
        ----------
        program_id : str
            The ID of the loyalty program or the keyword `main`. Either value can be used to retrieve the single loyalty program that belongs to the seller.

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

        Returns
        -------
        GetLoyaltyProgramResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


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


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

    async def calculate(
        self,
        program_id: str,
        *,
        order_id: typing.Optional[str] = OMIT,
        transaction_amount_money: typing.Optional[MoneyParams] = OMIT,
        loyalty_account_id: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CalculateLoyaltyPointsResponse:
        """
        Calculates the number of points a buyer can earn from a purchase. Applications might call this endpoint
        to display the points to the buyer.

        - If you are using the Orders API to manage orders, provide the `order_id` and (optional) `loyalty_account_id`.
        Square reads the order to compute the points earned from the base loyalty program and an associated
        [loyalty promotion](entity:LoyaltyPromotion).

        - If you are not using the Orders API to manage orders, provide `transaction_amount_money` with the
        purchase amount. Square uses this amount to calculate the points earned from the base loyalty program,
        but not points earned from a loyalty promotion. For spend-based and visit-based programs, the `tax_mode`
        setting of the accrual rule indicates how taxes should be treated for loyalty points accrual.
        If the purchase qualifies for program points, call
        [ListLoyaltyPromotions](api-endpoint:Loyalty-ListLoyaltyPromotions) and perform a client-side computation
        to calculate whether the purchase also qualifies for promotion points. For more information, see
        [Calculating promotion points](https://developer.squareup.com/docs/loyalty-api/loyalty-promotions#calculate-promotion-points).

        Parameters
        ----------
        program_id : str
            The ID of the [loyalty program](entity:LoyaltyProgram), which defines the rules for accruing points.

        order_id : typing.Optional[str]
            The [order](entity:Order) ID for which to calculate the points.
            Specify this field if your application uses the Orders API to process orders.
            Otherwise, specify the `transaction_amount_money`.

        transaction_amount_money : typing.Optional[MoneyParams]
            The purchase amount for which to calculate the points.
            Specify this field if your application does not use the Orders API to process orders.
            Otherwise, specify the `order_id`.

        loyalty_account_id : typing.Optional[str]
            The ID of the target [loyalty account](entity:LoyaltyAccount). Optionally specify this field
            if your application uses the Orders API to process orders.

            If specified, the `promotion_points` field in the response shows the number of points the buyer would
            earn from the purchase. In this case, Square uses the account ID to determine whether the promotion's
            `trigger_limit` (the maximum number of times that a buyer can trigger the promotion) has been reached.
            If not specified, the `promotion_points` field shows the number of points the purchase qualifies
            for regardless of the trigger limit.

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

        Returns
        -------
        CalculateLoyaltyPointsResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.loyalty.programs.calculate(
                program_id="program_id",
                order_id="RFZfrdtm3mhO1oGzf5Cx7fEMsmGZY",
                loyalty_account_id="79b807d2-d786-46a9-933b-918028d7a8c5",
            )


        asyncio.run(main())
        """
        response = await self._raw_client.calculate(
            program_id,
            order_id=order_id,
            transaction_amount_money=transaction_amount_money,
            loyalty_account_id=loyalty_account_id,
            request_options=request_options,
        )
        return response.data
