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

import typing
from ...core.client_wrapper import SyncClientWrapper
from .raw_client import RawPaymentLinksClient
from ...core.request_options import RequestOptions
from ...core.pagination import SyncPager
from ...types.payment_link import PaymentLink
from ...types.list_payment_links_response import ListPaymentLinksResponse
from ...core.unchecked_base_model import construct_type
from json.decoder import JSONDecodeError
from ...core.api_error import ApiError
from ...requests.quick_pay import QuickPayParams
from ...requests.order import OrderParams
from ...requests.checkout_options import CheckoutOptionsParams
from ...requests.pre_populated_data import PrePopulatedDataParams
from ...types.create_payment_link_response import CreatePaymentLinkResponse
from ...types.get_payment_link_response import GetPaymentLinkResponse
from ...requests.payment_link import PaymentLinkParams
from ...types.update_payment_link_response import UpdatePaymentLinkResponse
from ...types.delete_payment_link_response import DeletePaymentLinkResponse
from ...core.client_wrapper import AsyncClientWrapper
from .raw_client import AsyncRawPaymentLinksClient
from ...core.pagination import AsyncPager

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


class PaymentLinksClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawPaymentLinksClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        RawPaymentLinksClient
        """
        return self._raw_client

    def list(
        self,
        *,
        cursor: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[PaymentLink]:
        """
        Lists all payment links.

        Parameters
        ----------
        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.
            If a cursor is not provided, the endpoint returns the first page of the results.
            For more  information, see [Pagination](https://developer.squareup.com/docs/build-basics/common-api-patterns/pagination).

        limit : typing.Optional[int]
            A limit on the number of results to return per page. The limit is advisory and
            the implementation might return more or less results. If the supplied limit is negative, zero, or
            greater than the maximum limit of 1000, it is ignored.

            Default value: `100`

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

        Returns
        -------
        SyncPager[PaymentLink]
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        response = client.checkout.payment_links.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/online-checkout/payment-links",
            method="GET",
            params={
                "cursor": cursor,
                "limit": limit,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListPaymentLinksResponse,
                    construct_type(
                        type_=ListPaymentLinksResponse,  # 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(
                    cursor=_parsed_next,
                    limit=limit,
                    request_options=request_options,
                )
                _items = _parsed_response.payment_links
                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 create(
        self,
        *,
        idempotency_key: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        quick_pay: typing.Optional[QuickPayParams] = OMIT,
        order: typing.Optional[OrderParams] = OMIT,
        checkout_options: typing.Optional[CheckoutOptionsParams] = OMIT,
        pre_populated_data: typing.Optional[PrePopulatedDataParams] = OMIT,
        payment_note: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreatePaymentLinkResponse:
        """
        Creates a Square-hosted checkout page. Applications can share the resulting payment link with their buyer to pay for goods and services.

        Parameters
        ----------
        idempotency_key : typing.Optional[str]
            A unique string that identifies this `CreatePaymentLinkRequest` request.
            If you do not provide a unique string (or provide an empty string as the value),
            the endpoint treats each request as independent.

            For more information, see [Idempotency](https://developer.squareup.com/docs/working-with-apis/idempotency).

        description : typing.Optional[str]
            A description of the payment link. You provide this optional description that is useful in your
            application context. It is not used anywhere.

        quick_pay : typing.Optional[QuickPayParams]
            Describes an ad hoc item and price for which to generate a quick pay checkout link.
            For more information,
            see [Quick Pay Checkout](https://developer.squareup.com/docs/checkout-api/quick-pay-checkout).

        order : typing.Optional[OrderParams]
            Describes the `Order` for which to create a checkout link.
            For more information,
            see [Square Order Checkout](https://developer.squareup.com/docs/checkout-api/square-order-checkout).

        checkout_options : typing.Optional[CheckoutOptionsParams]
            Describes optional fields to add to the resulting checkout page.
            For more information,
            see [Optional Checkout Configurations](https://developer.squareup.com/docs/checkout-api/optional-checkout-configurations).

        pre_populated_data : typing.Optional[PrePopulatedDataParams]
            Describes fields to prepopulate in the resulting checkout page.
            For more information, see [Prepopulate the shipping address](https://developer.squareup.com/docs/checkout-api/optional-checkout-configurations#prepopulate-the-shipping-address).

        payment_note : typing.Optional[str]
            A note for the payment. After processing the payment, Square adds this note to the resulting `Payment`.

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

        Returns
        -------
        CreatePaymentLinkResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.checkout.payment_links.create(
            idempotency_key="cd9e25dc-d9f2-4430-aedb-61605070e95f",
            quick_pay={
                "name": "Auto Detailing",
                "price_money": {"amount": 10000, "currency": "USD"},
                "location_id": "A9Y43N9ABXZBP",
            },
        )
        """
        response = self._raw_client.create(
            idempotency_key=idempotency_key,
            description=description,
            quick_pay=quick_pay,
            order=order,
            checkout_options=checkout_options,
            pre_populated_data=pre_populated_data,
            payment_note=payment_note,
            request_options=request_options,
        )
        return response.data

    def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetPaymentLinkResponse:
        """
        Retrieves a payment link.

        Parameters
        ----------
        id : str
            The ID of link to retrieve.

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

        Returns
        -------
        GetPaymentLinkResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.checkout.payment_links.get(
            id="id",
        )
        """
        response = self._raw_client.get(id, request_options=request_options)
        return response.data

    def update(
        self, id: str, *, payment_link: PaymentLinkParams, request_options: typing.Optional[RequestOptions] = None
    ) -> UpdatePaymentLinkResponse:
        """
        Updates a payment link. You can update the `payment_link` fields such as
        `description`, `checkout_options`, and  `pre_populated_data`.
        You cannot update other fields such as the `order_id`, `version`, `URL`, or `timestamp` field.

        Parameters
        ----------
        id : str
            The ID of the payment link to update.

        payment_link : PaymentLinkParams
            The `payment_link` object describing the updates to apply.
            For more information, see [Update a payment link](https://developer.squareup.com/docs/checkout-api/manage-checkout#update-a-payment-link).

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

        Returns
        -------
        UpdatePaymentLinkResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.checkout.payment_links.update(
            id="id",
            payment_link={
                "version": 1,
                "checkout_options": {"ask_for_shipping_address": True},
            },
        )
        """
        response = self._raw_client.update(id, payment_link=payment_link, request_options=request_options)
        return response.data

    def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> DeletePaymentLinkResponse:
        """
        Deletes a payment link.

        Parameters
        ----------
        id : str
            The ID of the payment link to delete.

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

        Returns
        -------
        DeletePaymentLinkResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.checkout.payment_links.delete(
            id="id",
        )
        """
        response = self._raw_client.delete(id, request_options=request_options)
        return response.data


class AsyncPaymentLinksClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawPaymentLinksClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        AsyncRawPaymentLinksClient
        """
        return self._raw_client

    async def list(
        self,
        *,
        cursor: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[PaymentLink]:
        """
        Lists all payment links.

        Parameters
        ----------
        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.
            If a cursor is not provided, the endpoint returns the first page of the results.
            For more  information, see [Pagination](https://developer.squareup.com/docs/build-basics/common-api-patterns/pagination).

        limit : typing.Optional[int]
            A limit on the number of results to return per page. The limit is advisory and
            the implementation might return more or less results. If the supplied limit is negative, zero, or
            greater than the maximum limit of 1000, it is ignored.

            Default value: `100`

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

        Returns
        -------
        AsyncPager[PaymentLink]
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            response = await client.checkout.payment_links.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/online-checkout/payment-links",
            method="GET",
            params={
                "cursor": cursor,
                "limit": limit,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListPaymentLinksResponse,
                    construct_type(
                        type_=ListPaymentLinksResponse,  # 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(
                    cursor=_parsed_next,
                    limit=limit,
                    request_options=request_options,
                )
                _items = _parsed_response.payment_links
                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 create(
        self,
        *,
        idempotency_key: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        quick_pay: typing.Optional[QuickPayParams] = OMIT,
        order: typing.Optional[OrderParams] = OMIT,
        checkout_options: typing.Optional[CheckoutOptionsParams] = OMIT,
        pre_populated_data: typing.Optional[PrePopulatedDataParams] = OMIT,
        payment_note: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreatePaymentLinkResponse:
        """
        Creates a Square-hosted checkout page. Applications can share the resulting payment link with their buyer to pay for goods and services.

        Parameters
        ----------
        idempotency_key : typing.Optional[str]
            A unique string that identifies this `CreatePaymentLinkRequest` request.
            If you do not provide a unique string (or provide an empty string as the value),
            the endpoint treats each request as independent.

            For more information, see [Idempotency](https://developer.squareup.com/docs/working-with-apis/idempotency).

        description : typing.Optional[str]
            A description of the payment link. You provide this optional description that is useful in your
            application context. It is not used anywhere.

        quick_pay : typing.Optional[QuickPayParams]
            Describes an ad hoc item and price for which to generate a quick pay checkout link.
            For more information,
            see [Quick Pay Checkout](https://developer.squareup.com/docs/checkout-api/quick-pay-checkout).

        order : typing.Optional[OrderParams]
            Describes the `Order` for which to create a checkout link.
            For more information,
            see [Square Order Checkout](https://developer.squareup.com/docs/checkout-api/square-order-checkout).

        checkout_options : typing.Optional[CheckoutOptionsParams]
            Describes optional fields to add to the resulting checkout page.
            For more information,
            see [Optional Checkout Configurations](https://developer.squareup.com/docs/checkout-api/optional-checkout-configurations).

        pre_populated_data : typing.Optional[PrePopulatedDataParams]
            Describes fields to prepopulate in the resulting checkout page.
            For more information, see [Prepopulate the shipping address](https://developer.squareup.com/docs/checkout-api/optional-checkout-configurations#prepopulate-the-shipping-address).

        payment_note : typing.Optional[str]
            A note for the payment. After processing the payment, Square adds this note to the resulting `Payment`.

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

        Returns
        -------
        CreatePaymentLinkResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.checkout.payment_links.create(
                idempotency_key="cd9e25dc-d9f2-4430-aedb-61605070e95f",
                quick_pay={
                    "name": "Auto Detailing",
                    "price_money": {"amount": 10000, "currency": "USD"},
                    "location_id": "A9Y43N9ABXZBP",
                },
            )


        asyncio.run(main())
        """
        response = await self._raw_client.create(
            idempotency_key=idempotency_key,
            description=description,
            quick_pay=quick_pay,
            order=order,
            checkout_options=checkout_options,
            pre_populated_data=pre_populated_data,
            payment_note=payment_note,
            request_options=request_options,
        )
        return response.data

    async def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetPaymentLinkResponse:
        """
        Retrieves a payment link.

        Parameters
        ----------
        id : str
            The ID of link to retrieve.

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

        Returns
        -------
        GetPaymentLinkResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.checkout.payment_links.get(
                id="id",
            )


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

    async def update(
        self, id: str, *, payment_link: PaymentLinkParams, request_options: typing.Optional[RequestOptions] = None
    ) -> UpdatePaymentLinkResponse:
        """
        Updates a payment link. You can update the `payment_link` fields such as
        `description`, `checkout_options`, and  `pre_populated_data`.
        You cannot update other fields such as the `order_id`, `version`, `URL`, or `timestamp` field.

        Parameters
        ----------
        id : str
            The ID of the payment link to update.

        payment_link : PaymentLinkParams
            The `payment_link` object describing the updates to apply.
            For more information, see [Update a payment link](https://developer.squareup.com/docs/checkout-api/manage-checkout#update-a-payment-link).

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

        Returns
        -------
        UpdatePaymentLinkResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.checkout.payment_links.update(
                id="id",
                payment_link={
                    "version": 1,
                    "checkout_options": {"ask_for_shipping_address": True},
                },
            )


        asyncio.run(main())
        """
        response = await self._raw_client.update(id, payment_link=payment_link, request_options=request_options)
        return response.data

    async def delete(
        self, id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> DeletePaymentLinkResponse:
        """
        Deletes a payment link.

        Parameters
        ----------
        id : str
            The ID of the payment link to delete.

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

        Returns
        -------
        DeletePaymentLinkResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.checkout.payment_links.delete(
                id="id",
            )


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