# 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.serialization import convert_and_respect_annotation_metadata
from ...core.unchecked_base_model import construct_type
from ...requests.checkout_options import CheckoutOptionsParams
from ...requests.order import OrderParams
from ...requests.payment_link import PaymentLinkParams
from ...requests.pre_populated_data import PrePopulatedDataParams
from ...requests.quick_pay import QuickPayParams
from ...types.create_payment_link_response import CreatePaymentLinkResponse
from ...types.delete_payment_link_response import DeletePaymentLinkResponse
from ...types.get_payment_link_response import GetPaymentLinkResponse
from ...types.list_payment_links_response import ListPaymentLinksResponse
from ...types.payment_link import PaymentLink
from ...types.update_payment_link_response import UpdatePaymentLinkResponse

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


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

    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
        """
        _response = self._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(),
                    ),
                )
                _items = _parsed_response.payment_links
                _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,
                )
                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 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,
    ) -> HttpResponse[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
        -------
        HttpResponse[CreatePaymentLinkResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/online-checkout/payment-links",
            method="POST",
            json={
                "idempotency_key": idempotency_key,
                "description": description,
                "quick_pay": convert_and_respect_annotation_metadata(
                    object_=quick_pay, annotation=QuickPayParams, direction="write"
                ),
                "order": convert_and_respect_annotation_metadata(
                    object_=order, annotation=OrderParams, direction="write"
                ),
                "checkout_options": convert_and_respect_annotation_metadata(
                    object_=checkout_options, annotation=CheckoutOptionsParams, direction="write"
                ),
                "pre_populated_data": convert_and_respect_annotation_metadata(
                    object_=pre_populated_data, annotation=PrePopulatedDataParams, direction="write"
                ),
                "payment_note": payment_note,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreatePaymentLinkResponse,
                    construct_type(
                        type_=CreatePaymentLinkResponse,  # 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 get(
        self, id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[GetPaymentLinkResponse]:
        """
        Retrieves a payment link.

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

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

        Returns
        -------
        HttpResponse[GetPaymentLinkResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/online-checkout/payment-links/{jsonable_encoder(id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetPaymentLinkResponse,
                    construct_type(
                        type_=GetPaymentLinkResponse,  # 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 update(
        self, id: str, *, payment_link: PaymentLinkParams, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[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
        -------
        HttpResponse[UpdatePaymentLinkResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/online-checkout/payment-links/{jsonable_encoder(id)}",
            method="PUT",
            json={
                "payment_link": convert_and_respect_annotation_metadata(
                    object_=payment_link, annotation=PaymentLinkParams, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpdatePaymentLinkResponse,
                    construct_type(
                        type_=UpdatePaymentLinkResponse,  # 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 delete(
        self, id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[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
        -------
        HttpResponse[DeletePaymentLinkResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/online-checkout/payment-links/{jsonable_encoder(id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DeletePaymentLinkResponse,
                    construct_type(
                        type_=DeletePaymentLinkResponse,  # 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)


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

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

                async def _get_next():
                    return await self.list(
                        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 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,
    ) -> AsyncHttpResponse[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
        -------
        AsyncHttpResponse[CreatePaymentLinkResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/online-checkout/payment-links",
            method="POST",
            json={
                "idempotency_key": idempotency_key,
                "description": description,
                "quick_pay": convert_and_respect_annotation_metadata(
                    object_=quick_pay, annotation=QuickPayParams, direction="write"
                ),
                "order": convert_and_respect_annotation_metadata(
                    object_=order, annotation=OrderParams, direction="write"
                ),
                "checkout_options": convert_and_respect_annotation_metadata(
                    object_=checkout_options, annotation=CheckoutOptionsParams, direction="write"
                ),
                "pre_populated_data": convert_and_respect_annotation_metadata(
                    object_=pre_populated_data, annotation=PrePopulatedDataParams, direction="write"
                ),
                "payment_note": payment_note,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreatePaymentLinkResponse,
                    construct_type(
                        type_=CreatePaymentLinkResponse,  # 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 get(
        self, id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[GetPaymentLinkResponse]:
        """
        Retrieves a payment link.

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

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

        Returns
        -------
        AsyncHttpResponse[GetPaymentLinkResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/online-checkout/payment-links/{jsonable_encoder(id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetPaymentLinkResponse,
                    construct_type(
                        type_=GetPaymentLinkResponse,  # 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 update(
        self, id: str, *, payment_link: PaymentLinkParams, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[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
        -------
        AsyncHttpResponse[UpdatePaymentLinkResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/online-checkout/payment-links/{jsonable_encoder(id)}",
            method="PUT",
            json={
                "payment_link": convert_and_respect_annotation_metadata(
                    object_=payment_link, annotation=PaymentLinkParams, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpdatePaymentLinkResponse,
                    construct_type(
                        type_=UpdatePaymentLinkResponse,  # 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 delete(
        self, id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[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
        -------
        AsyncHttpResponse[DeletePaymentLinkResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/online-checkout/payment-links/{jsonable_encoder(id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DeletePaymentLinkResponse,
                    construct_type(
                        type_=DeletePaymentLinkResponse,  # 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)
