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

import typing
from ...core.client_wrapper import SyncClientWrapper
from .raw_client import RawCustomAttributeDefinitionsClient
from ...core.request_options import RequestOptions
from ...core.pagination import SyncPager
from ...types.custom_attribute_definition import CustomAttributeDefinition
from ...types.list_booking_custom_attribute_definitions_response import ListBookingCustomAttributeDefinitionsResponse
from ...core.unchecked_base_model import construct_type
from json.decoder import JSONDecodeError
from ...core.api_error import ApiError
from ...requests.custom_attribute_definition import CustomAttributeDefinitionParams
from ...types.create_booking_custom_attribute_definition_response import CreateBookingCustomAttributeDefinitionResponse
from ...types.retrieve_booking_custom_attribute_definition_response import (
    RetrieveBookingCustomAttributeDefinitionResponse,
)
from ...types.update_booking_custom_attribute_definition_response import UpdateBookingCustomAttributeDefinitionResponse
from ...types.delete_booking_custom_attribute_definition_response import DeleteBookingCustomAttributeDefinitionResponse
from ...core.client_wrapper import AsyncClientWrapper
from .raw_client import AsyncRawCustomAttributeDefinitionsClient
from ...core.pagination import AsyncPager

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


class CustomAttributeDefinitionsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawCustomAttributeDefinitionsClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        RawCustomAttributeDefinitionsClient
        """
        return self._raw_client

    def list(
        self,
        *,
        limit: typing.Optional[int] = None,
        cursor: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[CustomAttributeDefinition]:
        """
        Get all bookings custom attribute definitions.

        To call this endpoint with buyer-level permissions, set `APPOINTMENTS_READ` for the OAuth scope.
        To call this endpoint with seller-level permissions, set `APPOINTMENTS_ALL_READ` and `APPOINTMENTS_READ` for the OAuth scope.

        Parameters
        ----------
        limit : typing.Optional[int]
            The maximum number of results to return in a single paged response. This limit is advisory.
            The response might contain more or fewer results. The minimum value is 1 and the maximum value is 100.
            The default value is 20. For more information, see [Pagination](https://developer.squareup.com/docs/build-basics/common-api-patterns/pagination).

        cursor : typing.Optional[str]
            The cursor returned in the paged response from the previous call to this endpoint.
            Provide this cursor to retrieve the next page of results for your original request.
            For more information, see [Pagination](https://developer.squareup.com/docs/build-basics/common-api-patterns/pagination).

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

        Returns
        -------
        SyncPager[CustomAttributeDefinition]
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        response = client.bookings.custom_attribute_definitions.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/bookings/custom-attribute-definitions",
            method="GET",
            params={
                "limit": limit,
                "cursor": cursor,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListBookingCustomAttributeDefinitionsResponse,
                    construct_type(
                        type_=ListBookingCustomAttributeDefinitionsResponse,  # 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(
                    limit=limit,
                    cursor=_parsed_next,
                    request_options=request_options,
                )
                _items = _parsed_response.custom_attribute_definitions
                return SyncPager(has_next=_has_next, items=_items, get_next=_get_next)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def create(
        self,
        *,
        custom_attribute_definition: CustomAttributeDefinitionParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateBookingCustomAttributeDefinitionResponse:
        """
        Creates a bookings custom attribute definition.

        To call this endpoint with buyer-level permissions, set `APPOINTMENTS_WRITE` for the OAuth scope.
        To call this endpoint with seller-level permissions, set `APPOINTMENTS_ALL_WRITE` and `APPOINTMENTS_WRITE` for the OAuth scope.

        For calls to this endpoint with seller-level permissions to succeed, the seller must have subscribed to *Appointments Plus*
        or *Appointments Premium*.

        Parameters
        ----------
        custom_attribute_definition : CustomAttributeDefinitionParams
            The custom attribute definition to create, with the following fields:

            - `key`

            - `name`. If provided, `name` must be unique (case-sensitive) across all visible booking-related custom attribute
            definitions for the seller.

            - `description`

            - `visibility`. Note that all custom attributes are visible in exported booking data, including those set to
            `VISIBILITY_HIDDEN`.

            - `schema`. With the exception of the `Selection` data type, the `schema` is specified as a
            simple URL to the JSON schema definition hosted on the Square CDN. For more information, see
            [Specifying the schema](https://developer.squareup.com/docs/booking-custom-attributes-api/custom-attribute-definitions#specify-schema).

        idempotency_key : typing.Optional[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).

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

        Returns
        -------
        CreateBookingCustomAttributeDefinitionResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.bookings.custom_attribute_definitions.create(
            custom_attribute_definition={},
        )
        """
        response = self._raw_client.create(
            custom_attribute_definition=custom_attribute_definition,
            idempotency_key=idempotency_key,
            request_options=request_options,
        )
        return response.data

    def get(
        self, key: str, *, version: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None
    ) -> RetrieveBookingCustomAttributeDefinitionResponse:
        """
        Retrieves a bookings custom attribute definition.

        To call this endpoint with buyer-level permissions, set `APPOINTMENTS_READ` for the OAuth scope.
        To call this endpoint with seller-level permissions, set `APPOINTMENTS_ALL_READ` and `APPOINTMENTS_READ` for the OAuth scope.

        Parameters
        ----------
        key : str
            The key of the custom attribute definition to retrieve. If the requesting application
            is not the definition owner, you must use the qualified key.

        version : typing.Optional[int]
            The current version of the custom attribute definition, which is used for strongly consistent
            reads to guarantee that you receive the most up-to-date data. When included in the request,
            Square returns the specified version or a higher version if one exists. If the specified version
            is higher than the current version, Square returns a `BAD_REQUEST` error.

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

        Returns
        -------
        RetrieveBookingCustomAttributeDefinitionResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.bookings.custom_attribute_definitions.get(
            key="key",
        )
        """
        response = self._raw_client.get(key, version=version, request_options=request_options)
        return response.data

    def update(
        self,
        key: str,
        *,
        custom_attribute_definition: CustomAttributeDefinitionParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> UpdateBookingCustomAttributeDefinitionResponse:
        """
        Updates a bookings custom attribute definition.

        To call this endpoint with buyer-level permissions, set `APPOINTMENTS_WRITE` for the OAuth scope.
        To call this endpoint with seller-level permissions, set `APPOINTMENTS_ALL_WRITE` and `APPOINTMENTS_WRITE` for the OAuth scope.

        For calls to this endpoint with seller-level permissions to succeed, the seller must have subscribed to *Appointments Plus*
        or *Appointments Premium*.

        Parameters
        ----------
        key : str
            The key of the custom attribute definition to update.

        custom_attribute_definition : CustomAttributeDefinitionParams
            The custom attribute definition that contains the fields to update. Only the following fields can be updated:
            - `name`
            - `description`
            - `visibility`
            - `schema` for a `Selection` data type. Only changes to the named options or the maximum number of allowed
            selections are supported.

            For more information, see
            [Updatable definition fields](https://developer.squareup.com/docs/booking-custom-attributes-api/custom-attribute-definitions#updatable-definition-fields).

            To enable [optimistic concurrency](https://developer.squareup.com/docs/build-basics/common-api-patterns/optimistic-concurrency)
            control, include the optional `version` field and specify the current version of the custom attribute definition.

        idempotency_key : typing.Optional[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).

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

        Returns
        -------
        UpdateBookingCustomAttributeDefinitionResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.bookings.custom_attribute_definitions.update(
            key="key",
            custom_attribute_definition={},
        )
        """
        response = self._raw_client.update(
            key,
            custom_attribute_definition=custom_attribute_definition,
            idempotency_key=idempotency_key,
            request_options=request_options,
        )
        return response.data

    def delete(
        self, key: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> DeleteBookingCustomAttributeDefinitionResponse:
        """
        Deletes a bookings custom attribute definition.

        To call this endpoint with buyer-level permissions, set `APPOINTMENTS_WRITE` for the OAuth scope.
        To call this endpoint with seller-level permissions, set `APPOINTMENTS_ALL_WRITE` and `APPOINTMENTS_WRITE` for the OAuth scope.

        For calls to this endpoint with seller-level permissions to succeed, the seller must have subscribed to *Appointments Plus*
        or *Appointments Premium*.

        Parameters
        ----------
        key : str
            The key of the custom attribute definition to delete.

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

        Returns
        -------
        DeleteBookingCustomAttributeDefinitionResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.bookings.custom_attribute_definitions.delete(
            key="key",
        )
        """
        response = self._raw_client.delete(key, request_options=request_options)
        return response.data


class AsyncCustomAttributeDefinitionsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawCustomAttributeDefinitionsClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        AsyncRawCustomAttributeDefinitionsClient
        """
        return self._raw_client

    async def list(
        self,
        *,
        limit: typing.Optional[int] = None,
        cursor: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[CustomAttributeDefinition]:
        """
        Get all bookings custom attribute definitions.

        To call this endpoint with buyer-level permissions, set `APPOINTMENTS_READ` for the OAuth scope.
        To call this endpoint with seller-level permissions, set `APPOINTMENTS_ALL_READ` and `APPOINTMENTS_READ` for the OAuth scope.

        Parameters
        ----------
        limit : typing.Optional[int]
            The maximum number of results to return in a single paged response. This limit is advisory.
            The response might contain more or fewer results. The minimum value is 1 and the maximum value is 100.
            The default value is 20. For more information, see [Pagination](https://developer.squareup.com/docs/build-basics/common-api-patterns/pagination).

        cursor : typing.Optional[str]
            The cursor returned in the paged response from the previous call to this endpoint.
            Provide this cursor to retrieve the next page of results for your original request.
            For more information, see [Pagination](https://developer.squareup.com/docs/build-basics/common-api-patterns/pagination).

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

        Returns
        -------
        AsyncPager[CustomAttributeDefinition]
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            response = await client.bookings.custom_attribute_definitions.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/bookings/custom-attribute-definitions",
            method="GET",
            params={
                "limit": limit,
                "cursor": cursor,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListBookingCustomAttributeDefinitionsResponse,
                    construct_type(
                        type_=ListBookingCustomAttributeDefinitionsResponse,  # 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(
                    limit=limit,
                    cursor=_parsed_next,
                    request_options=request_options,
                )
                _items = _parsed_response.custom_attribute_definitions
                return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def create(
        self,
        *,
        custom_attribute_definition: CustomAttributeDefinitionParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateBookingCustomAttributeDefinitionResponse:
        """
        Creates a bookings custom attribute definition.

        To call this endpoint with buyer-level permissions, set `APPOINTMENTS_WRITE` for the OAuth scope.
        To call this endpoint with seller-level permissions, set `APPOINTMENTS_ALL_WRITE` and `APPOINTMENTS_WRITE` for the OAuth scope.

        For calls to this endpoint with seller-level permissions to succeed, the seller must have subscribed to *Appointments Plus*
        or *Appointments Premium*.

        Parameters
        ----------
        custom_attribute_definition : CustomAttributeDefinitionParams
            The custom attribute definition to create, with the following fields:

            - `key`

            - `name`. If provided, `name` must be unique (case-sensitive) across all visible booking-related custom attribute
            definitions for the seller.

            - `description`

            - `visibility`. Note that all custom attributes are visible in exported booking data, including those set to
            `VISIBILITY_HIDDEN`.

            - `schema`. With the exception of the `Selection` data type, the `schema` is specified as a
            simple URL to the JSON schema definition hosted on the Square CDN. For more information, see
            [Specifying the schema](https://developer.squareup.com/docs/booking-custom-attributes-api/custom-attribute-definitions#specify-schema).

        idempotency_key : typing.Optional[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).

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

        Returns
        -------
        CreateBookingCustomAttributeDefinitionResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.bookings.custom_attribute_definitions.create(
                custom_attribute_definition={},
            )


        asyncio.run(main())
        """
        response = await self._raw_client.create(
            custom_attribute_definition=custom_attribute_definition,
            idempotency_key=idempotency_key,
            request_options=request_options,
        )
        return response.data

    async def get(
        self, key: str, *, version: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None
    ) -> RetrieveBookingCustomAttributeDefinitionResponse:
        """
        Retrieves a bookings custom attribute definition.

        To call this endpoint with buyer-level permissions, set `APPOINTMENTS_READ` for the OAuth scope.
        To call this endpoint with seller-level permissions, set `APPOINTMENTS_ALL_READ` and `APPOINTMENTS_READ` for the OAuth scope.

        Parameters
        ----------
        key : str
            The key of the custom attribute definition to retrieve. If the requesting application
            is not the definition owner, you must use the qualified key.

        version : typing.Optional[int]
            The current version of the custom attribute definition, which is used for strongly consistent
            reads to guarantee that you receive the most up-to-date data. When included in the request,
            Square returns the specified version or a higher version if one exists. If the specified version
            is higher than the current version, Square returns a `BAD_REQUEST` error.

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

        Returns
        -------
        RetrieveBookingCustomAttributeDefinitionResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.bookings.custom_attribute_definitions.get(
                key="key",
            )


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

    async def update(
        self,
        key: str,
        *,
        custom_attribute_definition: CustomAttributeDefinitionParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> UpdateBookingCustomAttributeDefinitionResponse:
        """
        Updates a bookings custom attribute definition.

        To call this endpoint with buyer-level permissions, set `APPOINTMENTS_WRITE` for the OAuth scope.
        To call this endpoint with seller-level permissions, set `APPOINTMENTS_ALL_WRITE` and `APPOINTMENTS_WRITE` for the OAuth scope.

        For calls to this endpoint with seller-level permissions to succeed, the seller must have subscribed to *Appointments Plus*
        or *Appointments Premium*.

        Parameters
        ----------
        key : str
            The key of the custom attribute definition to update.

        custom_attribute_definition : CustomAttributeDefinitionParams
            The custom attribute definition that contains the fields to update. Only the following fields can be updated:
            - `name`
            - `description`
            - `visibility`
            - `schema` for a `Selection` data type. Only changes to the named options or the maximum number of allowed
            selections are supported.

            For more information, see
            [Updatable definition fields](https://developer.squareup.com/docs/booking-custom-attributes-api/custom-attribute-definitions#updatable-definition-fields).

            To enable [optimistic concurrency](https://developer.squareup.com/docs/build-basics/common-api-patterns/optimistic-concurrency)
            control, include the optional `version` field and specify the current version of the custom attribute definition.

        idempotency_key : typing.Optional[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).

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

        Returns
        -------
        UpdateBookingCustomAttributeDefinitionResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.bookings.custom_attribute_definitions.update(
                key="key",
                custom_attribute_definition={},
            )


        asyncio.run(main())
        """
        response = await self._raw_client.update(
            key,
            custom_attribute_definition=custom_attribute_definition,
            idempotency_key=idempotency_key,
            request_options=request_options,
        )
        return response.data

    async def delete(
        self, key: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> DeleteBookingCustomAttributeDefinitionResponse:
        """
        Deletes a bookings custom attribute definition.

        To call this endpoint with buyer-level permissions, set `APPOINTMENTS_WRITE` for the OAuth scope.
        To call this endpoint with seller-level permissions, set `APPOINTMENTS_ALL_WRITE` and `APPOINTMENTS_WRITE` for the OAuth scope.

        For calls to this endpoint with seller-level permissions to succeed, the seller must have subscribed to *Appointments Plus*
        or *Appointments Premium*.

        Parameters
        ----------
        key : str
            The key of the custom attribute definition to delete.

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

        Returns
        -------
        DeleteBookingCustomAttributeDefinitionResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.bookings.custom_attribute_definitions.delete(
                key="key",
            )


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