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

import typing
from ..core.client_wrapper import SyncClientWrapper
from ..requests.gift_card import GiftCardParams
from ..core.request_options import RequestOptions
from ..core.http_response import HttpResponse
from ..types.create_gift_card_response import CreateGiftCardResponse
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 ..types.get_gift_card_from_gan_response import GetGiftCardFromGanResponse
from ..types.get_gift_card_from_nonce_response import GetGiftCardFromNonceResponse
from ..types.link_customer_to_gift_card_response import LinkCustomerToGiftCardResponse
from ..core.jsonable_encoder import jsonable_encoder
from ..types.unlink_customer_from_gift_card_response import UnlinkCustomerFromGiftCardResponse
from ..types.get_gift_card_response import GetGiftCardResponse
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 RawGiftCardsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def create(
        self,
        *,
        idempotency_key: str,
        location_id: str,
        gift_card: GiftCardParams,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[CreateGiftCardResponse]:
        """
        Creates a digital gift card or registers a physical (plastic) gift card. The resulting gift card
        has a `PENDING` state. To activate a gift card so that it can be redeemed for purchases, call
        [CreateGiftCardActivity](api-endpoint:GiftCardActivities-CreateGiftCardActivity) and create an `ACTIVATE`
        activity with the initial balance. Alternatively, you can use [RefundPayment](api-endpoint:Refunds-RefundPayment)
        to refund a payment to the new gift card.

        Parameters
        ----------
        idempotency_key : str
            A unique identifier for this request, used to ensure idempotency. For more information,
            see [Idempotency](https://developer.squareup.com/docs/build-basics/common-api-patterns/idempotency).

        location_id : str
            The ID of the [location](entity:Location) where the gift card should be registered for
            reporting purposes. Gift cards can be redeemed at any of the seller's locations.

        gift_card : GiftCardParams
            The gift card to create. The `type` field is required for this request. The `gan_source`
            and `gan` fields are included as follows:

            To direct Square to generate a 16-digit GAN, omit `gan_source` and `gan`.

            To provide a custom GAN, include `gan_source` and `gan`.
            - For `gan_source`, specify `OTHER`.
            - For `gan`, provide a custom GAN containing 8 to 20 alphanumeric characters. The GAN must be
            unique for the seller and cannot start with the same bank identification number (BIN) as major
            credit cards. Do not use GANs that are easy to guess (such as 12345678) because they greatly
            increase the risk of fraud. It is the responsibility of the developer to ensure the security
            of their custom GANs. For more information, see
            [Custom GANs](https://developer.squareup.com/docs/gift-cards/using-gift-cards-api#custom-gans).

            To register an unused, physical gift card that the seller previously ordered from Square,
            include `gan` and provide the GAN that is printed on the gift card.

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

        Returns
        -------
        HttpResponse[CreateGiftCardResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/gift-cards",
            method="POST",
            json={
                "idempotency_key": idempotency_key,
                "location_id": location_id,
                "gift_card": convert_and_respect_annotation_metadata(
                    object_=gift_card, annotation=GiftCardParams, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateGiftCardResponse,
                    construct_type(
                        type_=CreateGiftCardResponse,  # 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)

    def get_from_gan(
        self, *, gan: str, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[GetGiftCardFromGanResponse]:
        """
        Retrieves a gift card using the gift card account number (GAN).

        Parameters
        ----------
        gan : str
            The gift card account number (GAN) of the gift card to retrieve.
            The maximum length of a GAN is 255 digits to account for third-party GANs that have been imported.
            Square-issued gift cards have 16-digit GANs.

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

        Returns
        -------
        HttpResponse[GetGiftCardFromGanResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/gift-cards/from-gan",
            method="POST",
            json={
                "gan": gan,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetGiftCardFromGanResponse,
                    construct_type(
                        type_=GetGiftCardFromGanResponse,  # 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)

    def get_from_nonce(
        self, *, nonce: str, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[GetGiftCardFromNonceResponse]:
        """
        Retrieves a gift card using a secure payment token that represents the gift card.

        Parameters
        ----------
        nonce : str
            The payment token of the gift card to retrieve. Payment tokens are generated by the
            Web Payments SDK or In-App Payments SDK.

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

        Returns
        -------
        HttpResponse[GetGiftCardFromNonceResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/gift-cards/from-nonce",
            method="POST",
            json={
                "nonce": nonce,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetGiftCardFromNonceResponse,
                    construct_type(
                        type_=GetGiftCardFromNonceResponse,  # 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)

    def link_customer(
        self, gift_card_id: str, *, customer_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[LinkCustomerToGiftCardResponse]:
        """
        Links a customer to a gift card, which is also referred to as adding a card on file.

        Parameters
        ----------
        gift_card_id : str
            The ID of the gift card to be linked.

        customer_id : str
            The ID of the customer to link to the gift card.

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

        Returns
        -------
        HttpResponse[LinkCustomerToGiftCardResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/gift-cards/{jsonable_encoder(gift_card_id)}/link-customer",
            method="POST",
            json={
                "customer_id": customer_id,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    LinkCustomerToGiftCardResponse,
                    construct_type(
                        type_=LinkCustomerToGiftCardResponse,  # 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)

    def unlink_customer(
        self, gift_card_id: str, *, customer_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[UnlinkCustomerFromGiftCardResponse]:
        """
        Unlinks a customer from a gift card, which is also referred to as removing a card on file.

        Parameters
        ----------
        gift_card_id : str
            The ID of the gift card to be unlinked.

        customer_id : str
            The ID of the customer to unlink from the gift card.

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

        Returns
        -------
        HttpResponse[UnlinkCustomerFromGiftCardResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/gift-cards/{jsonable_encoder(gift_card_id)}/unlink-customer",
            method="POST",
            json={
                "customer_id": customer_id,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UnlinkCustomerFromGiftCardResponse,
                    construct_type(
                        type_=UnlinkCustomerFromGiftCardResponse,  # 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)

    def get(
        self, id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[GetGiftCardResponse]:
        """
        Retrieves a gift card using the gift card ID.

        Parameters
        ----------
        id : str
            The ID of the gift card to retrieve.

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

        Returns
        -------
        HttpResponse[GetGiftCardResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/gift-cards/{jsonable_encoder(id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetGiftCardResponse,
                    construct_type(
                        type_=GetGiftCardResponse,  # 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 AsyncRawGiftCardsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def create(
        self,
        *,
        idempotency_key: str,
        location_id: str,
        gift_card: GiftCardParams,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[CreateGiftCardResponse]:
        """
        Creates a digital gift card or registers a physical (plastic) gift card. The resulting gift card
        has a `PENDING` state. To activate a gift card so that it can be redeemed for purchases, call
        [CreateGiftCardActivity](api-endpoint:GiftCardActivities-CreateGiftCardActivity) and create an `ACTIVATE`
        activity with the initial balance. Alternatively, you can use [RefundPayment](api-endpoint:Refunds-RefundPayment)
        to refund a payment to the new gift card.

        Parameters
        ----------
        idempotency_key : str
            A unique identifier for this request, used to ensure idempotency. For more information,
            see [Idempotency](https://developer.squareup.com/docs/build-basics/common-api-patterns/idempotency).

        location_id : str
            The ID of the [location](entity:Location) where the gift card should be registered for
            reporting purposes. Gift cards can be redeemed at any of the seller's locations.

        gift_card : GiftCardParams
            The gift card to create. The `type` field is required for this request. The `gan_source`
            and `gan` fields are included as follows:

            To direct Square to generate a 16-digit GAN, omit `gan_source` and `gan`.

            To provide a custom GAN, include `gan_source` and `gan`.
            - For `gan_source`, specify `OTHER`.
            - For `gan`, provide a custom GAN containing 8 to 20 alphanumeric characters. The GAN must be
            unique for the seller and cannot start with the same bank identification number (BIN) as major
            credit cards. Do not use GANs that are easy to guess (such as 12345678) because they greatly
            increase the risk of fraud. It is the responsibility of the developer to ensure the security
            of their custom GANs. For more information, see
            [Custom GANs](https://developer.squareup.com/docs/gift-cards/using-gift-cards-api#custom-gans).

            To register an unused, physical gift card that the seller previously ordered from Square,
            include `gan` and provide the GAN that is printed on the gift card.

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

        Returns
        -------
        AsyncHttpResponse[CreateGiftCardResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/gift-cards",
            method="POST",
            json={
                "idempotency_key": idempotency_key,
                "location_id": location_id,
                "gift_card": convert_and_respect_annotation_metadata(
                    object_=gift_card, annotation=GiftCardParams, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateGiftCardResponse,
                    construct_type(
                        type_=CreateGiftCardResponse,  # 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)

    async def get_from_gan(
        self, *, gan: str, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[GetGiftCardFromGanResponse]:
        """
        Retrieves a gift card using the gift card account number (GAN).

        Parameters
        ----------
        gan : str
            The gift card account number (GAN) of the gift card to retrieve.
            The maximum length of a GAN is 255 digits to account for third-party GANs that have been imported.
            Square-issued gift cards have 16-digit GANs.

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

        Returns
        -------
        AsyncHttpResponse[GetGiftCardFromGanResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/gift-cards/from-gan",
            method="POST",
            json={
                "gan": gan,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetGiftCardFromGanResponse,
                    construct_type(
                        type_=GetGiftCardFromGanResponse,  # 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)

    async def get_from_nonce(
        self, *, nonce: str, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[GetGiftCardFromNonceResponse]:
        """
        Retrieves a gift card using a secure payment token that represents the gift card.

        Parameters
        ----------
        nonce : str
            The payment token of the gift card to retrieve. Payment tokens are generated by the
            Web Payments SDK or In-App Payments SDK.

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

        Returns
        -------
        AsyncHttpResponse[GetGiftCardFromNonceResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/gift-cards/from-nonce",
            method="POST",
            json={
                "nonce": nonce,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetGiftCardFromNonceResponse,
                    construct_type(
                        type_=GetGiftCardFromNonceResponse,  # 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)

    async def link_customer(
        self, gift_card_id: str, *, customer_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[LinkCustomerToGiftCardResponse]:
        """
        Links a customer to a gift card, which is also referred to as adding a card on file.

        Parameters
        ----------
        gift_card_id : str
            The ID of the gift card to be linked.

        customer_id : str
            The ID of the customer to link to the gift card.

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

        Returns
        -------
        AsyncHttpResponse[LinkCustomerToGiftCardResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/gift-cards/{jsonable_encoder(gift_card_id)}/link-customer",
            method="POST",
            json={
                "customer_id": customer_id,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    LinkCustomerToGiftCardResponse,
                    construct_type(
                        type_=LinkCustomerToGiftCardResponse,  # 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)

    async def unlink_customer(
        self, gift_card_id: str, *, customer_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[UnlinkCustomerFromGiftCardResponse]:
        """
        Unlinks a customer from a gift card, which is also referred to as removing a card on file.

        Parameters
        ----------
        gift_card_id : str
            The ID of the gift card to be unlinked.

        customer_id : str
            The ID of the customer to unlink from the gift card.

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

        Returns
        -------
        AsyncHttpResponse[UnlinkCustomerFromGiftCardResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/gift-cards/{jsonable_encoder(gift_card_id)}/unlink-customer",
            method="POST",
            json={
                "customer_id": customer_id,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UnlinkCustomerFromGiftCardResponse,
                    construct_type(
                        type_=UnlinkCustomerFromGiftCardResponse,  # 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)

    async def get(
        self, id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[GetGiftCardResponse]:
        """
        Retrieves a gift card using the gift card ID.

        Parameters
        ----------
        id : str
            The ID of the gift card to retrieve.

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

        Returns
        -------
        AsyncHttpResponse[GetGiftCardResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/gift-cards/{jsonable_encoder(id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetGiftCardResponse,
                    construct_type(
                        type_=GetGiftCardResponse,  # 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)
