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

import typing
from ...core.client_wrapper import SyncClientWrapper
from ...requests.terminal_refund import TerminalRefundParams
from ...core.request_options import RequestOptions
from ...core.http_response import HttpResponse
from ...types.create_terminal_refund_response import CreateTerminalRefundResponse
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 ...requests.terminal_refund_query import TerminalRefundQueryParams
from ...types.search_terminal_refunds_response import SearchTerminalRefundsResponse
from ...types.get_terminal_refund_response import GetTerminalRefundResponse
from ...core.jsonable_encoder import jsonable_encoder
from ...types.cancel_terminal_refund_response import CancelTerminalRefundResponse
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 RawRefundsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def create(
        self,
        *,
        idempotency_key: str,
        refund: typing.Optional[TerminalRefundParams] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[CreateTerminalRefundResponse]:
        """
        Creates a request to refund an Interac payment completed on a Square Terminal. Refunds for Interac payments on a Square Terminal are supported only for Interac debit cards in Canada. Other refunds for Terminal payments should use the Refunds API. For more information, see [Refunds API](api:Refunds).

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

            See [Idempotency keys](https://developer.squareup.com/docs/build-basics/common-api-patterns/idempotency) for more information.

        refund : typing.Optional[TerminalRefundParams]
            The refund to create.

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

        Returns
        -------
        HttpResponse[CreateTerminalRefundResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/terminals/refunds",
            method="POST",
            json={
                "idempotency_key": idempotency_key,
                "refund": convert_and_respect_annotation_metadata(
                    object_=refund, annotation=TerminalRefundParams, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateTerminalRefundResponse,
                    construct_type(
                        type_=CreateTerminalRefundResponse,  # 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 search(
        self,
        *,
        query: typing.Optional[TerminalRefundQueryParams] = OMIT,
        cursor: typing.Optional[str] = OMIT,
        limit: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[SearchTerminalRefundsResponse]:
        """
        Retrieves a filtered list of Interac Terminal refund requests created by the seller making the request. Terminal refund requests are available for 30 days.

        Parameters
        ----------
        query : typing.Optional[TerminalRefundQueryParams]
            Queries the Terminal refunds based on given conditions and the sort order. Calling
            `SearchTerminalRefunds` without an explicit query parameter returns all available
            refunds with the default sort order.

        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.

        limit : typing.Optional[int]
            Limits the number of results returned for a single request.

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

        Returns
        -------
        HttpResponse[SearchTerminalRefundsResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/terminals/refunds/search",
            method="POST",
            json={
                "query": convert_and_respect_annotation_metadata(
                    object_=query, annotation=TerminalRefundQueryParams, direction="write"
                ),
                "cursor": cursor,
                "limit": limit,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SearchTerminalRefundsResponse,
                    construct_type(
                        type_=SearchTerminalRefundsResponse,  # 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, terminal_refund_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[GetTerminalRefundResponse]:
        """
        Retrieves an Interac Terminal refund object by ID. Terminal refund objects are available for 30 days.

        Parameters
        ----------
        terminal_refund_id : str
            The unique ID for the desired `TerminalRefund`.

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

        Returns
        -------
        HttpResponse[GetTerminalRefundResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/terminals/refunds/{jsonable_encoder(terminal_refund_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetTerminalRefundResponse,
                    construct_type(
                        type_=GetTerminalRefundResponse,  # 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 cancel(
        self, terminal_refund_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[CancelTerminalRefundResponse]:
        """
        Cancels an Interac Terminal refund request by refund request ID if the status of the request permits it.

        Parameters
        ----------
        terminal_refund_id : str
            The unique ID for the desired `TerminalRefund`.

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

        Returns
        -------
        HttpResponse[CancelTerminalRefundResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/terminals/refunds/{jsonable_encoder(terminal_refund_id)}/cancel",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CancelTerminalRefundResponse,
                    construct_type(
                        type_=CancelTerminalRefundResponse,  # 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 AsyncRawRefundsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def create(
        self,
        *,
        idempotency_key: str,
        refund: typing.Optional[TerminalRefundParams] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[CreateTerminalRefundResponse]:
        """
        Creates a request to refund an Interac payment completed on a Square Terminal. Refunds for Interac payments on a Square Terminal are supported only for Interac debit cards in Canada. Other refunds for Terminal payments should use the Refunds API. For more information, see [Refunds API](api:Refunds).

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

            See [Idempotency keys](https://developer.squareup.com/docs/build-basics/common-api-patterns/idempotency) for more information.

        refund : typing.Optional[TerminalRefundParams]
            The refund to create.

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

        Returns
        -------
        AsyncHttpResponse[CreateTerminalRefundResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/terminals/refunds",
            method="POST",
            json={
                "idempotency_key": idempotency_key,
                "refund": convert_and_respect_annotation_metadata(
                    object_=refund, annotation=TerminalRefundParams, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateTerminalRefundResponse,
                    construct_type(
                        type_=CreateTerminalRefundResponse,  # 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 search(
        self,
        *,
        query: typing.Optional[TerminalRefundQueryParams] = OMIT,
        cursor: typing.Optional[str] = OMIT,
        limit: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[SearchTerminalRefundsResponse]:
        """
        Retrieves a filtered list of Interac Terminal refund requests created by the seller making the request. Terminal refund requests are available for 30 days.

        Parameters
        ----------
        query : typing.Optional[TerminalRefundQueryParams]
            Queries the Terminal refunds based on given conditions and the sort order. Calling
            `SearchTerminalRefunds` without an explicit query parameter returns all available
            refunds with the default sort order.

        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.

        limit : typing.Optional[int]
            Limits the number of results returned for a single request.

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

        Returns
        -------
        AsyncHttpResponse[SearchTerminalRefundsResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/terminals/refunds/search",
            method="POST",
            json={
                "query": convert_and_respect_annotation_metadata(
                    object_=query, annotation=TerminalRefundQueryParams, direction="write"
                ),
                "cursor": cursor,
                "limit": limit,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SearchTerminalRefundsResponse,
                    construct_type(
                        type_=SearchTerminalRefundsResponse,  # 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, terminal_refund_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[GetTerminalRefundResponse]:
        """
        Retrieves an Interac Terminal refund object by ID. Terminal refund objects are available for 30 days.

        Parameters
        ----------
        terminal_refund_id : str
            The unique ID for the desired `TerminalRefund`.

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

        Returns
        -------
        AsyncHttpResponse[GetTerminalRefundResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/terminals/refunds/{jsonable_encoder(terminal_refund_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetTerminalRefundResponse,
                    construct_type(
                        type_=GetTerminalRefundResponse,  # 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 cancel(
        self, terminal_refund_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[CancelTerminalRefundResponse]:
        """
        Cancels an Interac Terminal refund request by refund request ID if the status of the request permits it.

        Parameters
        ----------
        terminal_refund_id : str
            The unique ID for the desired `TerminalRefund`.

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

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