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

import typing
from ..core.client_wrapper import SyncClientWrapper
from .raw_client import RawDisputesClient
from .evidence.client import EvidenceClient
from ..types.dispute_state import DisputeState
from ..core.request_options import RequestOptions
from ..core.pagination import SyncPager
from ..types.dispute import Dispute
from ..types.list_disputes_response import ListDisputesResponse
from ..core.unchecked_base_model import construct_type
from json.decoder import JSONDecodeError
from ..core.api_error import ApiError
from ..types.get_dispute_response import GetDisputeResponse
from ..types.accept_dispute_response import AcceptDisputeResponse
from ..requests.create_dispute_evidence_file_request import CreateDisputeEvidenceFileRequestParams
from .. import core
from ..types.create_dispute_evidence_file_response import CreateDisputeEvidenceFileResponse
from ..types.dispute_evidence_type import DisputeEvidenceType
from ..types.create_dispute_evidence_text_response import CreateDisputeEvidenceTextResponse
from ..types.submit_evidence_response import SubmitEvidenceResponse
from ..core.client_wrapper import AsyncClientWrapper
from .raw_client import AsyncRawDisputesClient
from .evidence.client import AsyncEvidenceClient
from ..core.pagination import AsyncPager

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


class DisputesClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawDisputesClient(client_wrapper=client_wrapper)
        self.evidence = EvidenceClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        RawDisputesClient
        """
        return self._raw_client

    def list(
        self,
        *,
        cursor: typing.Optional[str] = None,
        states: typing.Optional[DisputeState] = None,
        location_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[Dispute]:
        """
        Returns a list of disputes associated with a particular account.

        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.
            For more information, see [Pagination](https://developer.squareup.com/docs/build-basics/common-api-patterns/pagination).

        states : typing.Optional[DisputeState]
            The dispute states used to filter the result. If not specified, the endpoint returns all disputes.

        location_id : typing.Optional[str]
            The ID of the location for which to return a list of disputes.
            If not specified, the endpoint returns disputes associated with all locations.

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

        Returns
        -------
        SyncPager[Dispute]
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        response = client.disputes.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/disputes",
            method="GET",
            params={
                "cursor": cursor,
                "states": states,
                "location_id": location_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListDisputesResponse,
                    construct_type(
                        type_=ListDisputesResponse,  # 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,
                    states=states,
                    location_id=location_id,
                    request_options=request_options,
                )
                _items = _parsed_response.disputes
                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 get(self, dispute_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetDisputeResponse:
        """
        Returns details about a specific dispute.

        Parameters
        ----------
        dispute_id : str
            The ID of the dispute you want more details about.

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

        Returns
        -------
        GetDisputeResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.disputes.get(
            dispute_id="dispute_id",
        )
        """
        response = self._raw_client.get(dispute_id, request_options=request_options)
        return response.data

    def accept(
        self, dispute_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AcceptDisputeResponse:
        """
        Accepts the loss on a dispute. Square returns the disputed amount to the cardholder and
        updates the dispute state to ACCEPTED.

        Square debits the disputed amount from the seller’s Square account. If the Square account
        does not have sufficient funds, Square debits the associated bank account.

        Parameters
        ----------
        dispute_id : str
            The ID of the dispute you want to accept.

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

        Returns
        -------
        AcceptDisputeResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.disputes.accept(
            dispute_id="dispute_id",
        )
        """
        response = self._raw_client.accept(dispute_id, request_options=request_options)
        return response.data

    def create_evidence_file(
        self,
        dispute_id: str,
        *,
        request: typing.Optional[CreateDisputeEvidenceFileRequestParams] = OMIT,
        image_file: typing.Optional[core.File] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateDisputeEvidenceFileResponse:
        """
        Uploads a file to use as evidence in a dispute challenge. The endpoint accepts HTTP
        multipart/form-data file uploads in HEIC, HEIF, JPEG, PDF, PNG, and TIFF formats.

        Parameters
        ----------
        dispute_id : str
            The ID of the dispute for which you want to upload evidence.

        request : typing.Optional[CreateDisputeEvidenceFileRequestParams]

        image_file : typing.Optional[core.File]
            See core.File for more documentation

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

        Returns
        -------
        CreateDisputeEvidenceFileResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.disputes.create_evidence_file(
            dispute_id="dispute_id",
        )
        """
        response = self._raw_client.create_evidence_file(
            dispute_id, request=request, image_file=image_file, request_options=request_options
        )
        return response.data

    def create_evidence_text(
        self,
        dispute_id: str,
        *,
        idempotency_key: str,
        evidence_text: str,
        evidence_type: typing.Optional[DisputeEvidenceType] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateDisputeEvidenceTextResponse:
        """
        Uploads text to use as evidence for a dispute challenge.

        Parameters
        ----------
        dispute_id : str
            The ID of the dispute for which you want to upload evidence.

        idempotency_key : str
            A unique key identifying the request. For more information, see [Idempotency](https://developer.squareup.com/docs/working-with-apis/idempotency).

        evidence_text : str
            The evidence string.

        evidence_type : typing.Optional[DisputeEvidenceType]
            The type of evidence you are uploading.
            See [DisputeEvidenceType](#type-disputeevidencetype) for possible values

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

        Returns
        -------
        CreateDisputeEvidenceTextResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.disputes.create_evidence_text(
            dispute_id="dispute_id",
            idempotency_key="ed3ee3933d946f1514d505d173c82648",
            evidence_type="TRACKING_NUMBER",
            evidence_text="1Z8888888888888888",
        )
        """
        response = self._raw_client.create_evidence_text(
            dispute_id,
            idempotency_key=idempotency_key,
            evidence_text=evidence_text,
            evidence_type=evidence_type,
            request_options=request_options,
        )
        return response.data

    def submit_evidence(
        self, dispute_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> SubmitEvidenceResponse:
        """
        Submits evidence to the cardholder's bank.

        The evidence submitted by this endpoint includes evidence uploaded
        using the [CreateDisputeEvidenceFile](api-endpoint:Disputes-CreateDisputeEvidenceFile) and
        [CreateDisputeEvidenceText](api-endpoint:Disputes-CreateDisputeEvidenceText) endpoints and
        evidence automatically provided by Square, when available. Evidence cannot be removed from
        a dispute after submission.

        Parameters
        ----------
        dispute_id : str
            The ID of the dispute for which you want to submit evidence.

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

        Returns
        -------
        SubmitEvidenceResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.disputes.submit_evidence(
            dispute_id="dispute_id",
        )
        """
        response = self._raw_client.submit_evidence(dispute_id, request_options=request_options)
        return response.data


class AsyncDisputesClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawDisputesClient(client_wrapper=client_wrapper)
        self.evidence = AsyncEvidenceClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        AsyncRawDisputesClient
        """
        return self._raw_client

    async def list(
        self,
        *,
        cursor: typing.Optional[str] = None,
        states: typing.Optional[DisputeState] = None,
        location_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[Dispute]:
        """
        Returns a list of disputes associated with a particular account.

        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.
            For more information, see [Pagination](https://developer.squareup.com/docs/build-basics/common-api-patterns/pagination).

        states : typing.Optional[DisputeState]
            The dispute states used to filter the result. If not specified, the endpoint returns all disputes.

        location_id : typing.Optional[str]
            The ID of the location for which to return a list of disputes.
            If not specified, the endpoint returns disputes associated with all locations.

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

        Returns
        -------
        AsyncPager[Dispute]
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            response = await client.disputes.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/disputes",
            method="GET",
            params={
                "cursor": cursor,
                "states": states,
                "location_id": location_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListDisputesResponse,
                    construct_type(
                        type_=ListDisputesResponse,  # 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,
                    states=states,
                    location_id=location_id,
                    request_options=request_options,
                )
                _items = _parsed_response.disputes
                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 get(
        self, dispute_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> GetDisputeResponse:
        """
        Returns details about a specific dispute.

        Parameters
        ----------
        dispute_id : str
            The ID of the dispute you want more details about.

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

        Returns
        -------
        GetDisputeResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.disputes.get(
                dispute_id="dispute_id",
            )


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

    async def accept(
        self, dispute_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AcceptDisputeResponse:
        """
        Accepts the loss on a dispute. Square returns the disputed amount to the cardholder and
        updates the dispute state to ACCEPTED.

        Square debits the disputed amount from the seller’s Square account. If the Square account
        does not have sufficient funds, Square debits the associated bank account.

        Parameters
        ----------
        dispute_id : str
            The ID of the dispute you want to accept.

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

        Returns
        -------
        AcceptDisputeResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.disputes.accept(
                dispute_id="dispute_id",
            )


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

    async def create_evidence_file(
        self,
        dispute_id: str,
        *,
        request: typing.Optional[CreateDisputeEvidenceFileRequestParams] = OMIT,
        image_file: typing.Optional[core.File] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateDisputeEvidenceFileResponse:
        """
        Uploads a file to use as evidence in a dispute challenge. The endpoint accepts HTTP
        multipart/form-data file uploads in HEIC, HEIF, JPEG, PDF, PNG, and TIFF formats.

        Parameters
        ----------
        dispute_id : str
            The ID of the dispute for which you want to upload evidence.

        request : typing.Optional[CreateDisputeEvidenceFileRequestParams]

        image_file : typing.Optional[core.File]
            See core.File for more documentation

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

        Returns
        -------
        CreateDisputeEvidenceFileResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.disputes.create_evidence_file(
                dispute_id="dispute_id",
            )


        asyncio.run(main())
        """
        response = await self._raw_client.create_evidence_file(
            dispute_id, request=request, image_file=image_file, request_options=request_options
        )
        return response.data

    async def create_evidence_text(
        self,
        dispute_id: str,
        *,
        idempotency_key: str,
        evidence_text: str,
        evidence_type: typing.Optional[DisputeEvidenceType] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateDisputeEvidenceTextResponse:
        """
        Uploads text to use as evidence for a dispute challenge.

        Parameters
        ----------
        dispute_id : str
            The ID of the dispute for which you want to upload evidence.

        idempotency_key : str
            A unique key identifying the request. For more information, see [Idempotency](https://developer.squareup.com/docs/working-with-apis/idempotency).

        evidence_text : str
            The evidence string.

        evidence_type : typing.Optional[DisputeEvidenceType]
            The type of evidence you are uploading.
            See [DisputeEvidenceType](#type-disputeevidencetype) for possible values

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

        Returns
        -------
        CreateDisputeEvidenceTextResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.disputes.create_evidence_text(
                dispute_id="dispute_id",
                idempotency_key="ed3ee3933d946f1514d505d173c82648",
                evidence_type="TRACKING_NUMBER",
                evidence_text="1Z8888888888888888",
            )


        asyncio.run(main())
        """
        response = await self._raw_client.create_evidence_text(
            dispute_id,
            idempotency_key=idempotency_key,
            evidence_text=evidence_text,
            evidence_type=evidence_type,
            request_options=request_options,
        )
        return response.data

    async def submit_evidence(
        self, dispute_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> SubmitEvidenceResponse:
        """
        Submits evidence to the cardholder's bank.

        The evidence submitted by this endpoint includes evidence uploaded
        using the [CreateDisputeEvidenceFile](api-endpoint:Disputes-CreateDisputeEvidenceFile) and
        [CreateDisputeEvidenceText](api-endpoint:Disputes-CreateDisputeEvidenceText) endpoints and
        evidence automatically provided by Square, when available. Evidence cannot be removed from
        a dispute after submission.

        Parameters
        ----------
        dispute_id : str
            The ID of the dispute for which you want to submit evidence.

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

        Returns
        -------
        SubmitEvidenceResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.disputes.submit_evidence(
                dispute_id="dispute_id",
            )


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