# 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 ...types.visibility_filter import VisibilityFilter
from ...core.request_options import RequestOptions
from ...core.pagination import SyncPager
from ...types.custom_attribute_definition import CustomAttributeDefinition
from ...types.list_order_custom_attribute_definitions_response import ListOrderCustomAttributeDefinitionsResponse
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_order_custom_attribute_definition_response import CreateOrderCustomAttributeDefinitionResponse
from ...types.retrieve_order_custom_attribute_definition_response import RetrieveOrderCustomAttributeDefinitionResponse
from ...types.update_order_custom_attribute_definition_response import UpdateOrderCustomAttributeDefinitionResponse
from ...types.delete_order_custom_attribute_definition_response import DeleteOrderCustomAttributeDefinitionResponse
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,
        *,
        visibility_filter: typing.Optional[VisibilityFilter] = None,
        cursor: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[CustomAttributeDefinition]:
        """
        Lists the order-related [custom attribute definitions](entity:CustomAttributeDefinition) that belong to a Square seller account.

        When all response pages are retrieved, the results include all custom attribute definitions
        that are visible to the requesting application, including those that are created by other
        applications and set to `VISIBILITY_READ_ONLY` or `VISIBILITY_READ_WRITE_VALUES`. Note that
        seller-defined custom attributes (also known as custom fields) are always set to `VISIBILITY_READ_WRITE_VALUES`.

        Parameters
        ----------
        visibility_filter : typing.Optional[VisibilityFilter]
            Requests that all of the custom attributes be returned, or only those that are read-only or read-write.

        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/working-with-apis/pagination).

        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/working-with-apis/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.orders.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/orders/custom-attribute-definitions",
            method="GET",
            params={
                "visibility_filter": visibility_filter,
                "cursor": cursor,
                "limit": limit,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListOrderCustomAttributeDefinitionsResponse,
                    construct_type(
                        type_=ListOrderCustomAttributeDefinitionsResponse,  # 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(
                    visibility_filter=visibility_filter,
                    cursor=_parsed_next,
                    limit=limit,
                    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,
    ) -> CreateOrderCustomAttributeDefinitionResponse:
        """
        Creates an order-related custom attribute definition.  Use this endpoint to
        define a custom attribute that can be associated with orders.

        After creating a custom attribute definition, you can set the custom attribute for orders
        in the Square seller account.

        Parameters
        ----------
        custom_attribute_definition : CustomAttributeDefinitionParams
            The custom attribute definition to create. Note the following:
            - 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, including supported values and constraints, see
            [Specifying the schema](https://developer.squareup.com/docs/customer-custom-attributes-api/custom-attribute-definitions#specify-schema).
            - If provided, `name` must be unique (case-sensitive) across all visible customer-related custom attribute definitions for the seller.
            - All custom attributes are visible in exported customer data, including those set to `VISIBILITY_HIDDEN`.

        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
        -------
        CreateOrderCustomAttributeDefinitionResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.orders.custom_attribute_definitions.create(
            custom_attribute_definition={
                "key": "cover-count",
                "schema": {
                    "ref": "https://developer-production-s.squarecdn.com/schemas/v1/common.json#squareup.common.Number"
                },
                "name": "Cover count",
                "description": "The number of people seated at a table",
                "visibility": "VISIBILITY_READ_WRITE_VALUES",
            },
            idempotency_key="IDEMPOTENCY_KEY",
        )
        """
        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
    ) -> RetrieveOrderCustomAttributeDefinitionResponse:
        """
        Retrieves an order-related [custom attribute definition](entity:CustomAttributeDefinition) from a Square seller account.

        To retrieve a custom attribute definition created by another application, the `visibility`
        setting must be `VISIBILITY_READ_ONLY` or `VISIBILITY_READ_WRITE_VALUES`. Note that seller-defined custom attributes
        (also known as custom fields) are always set to `VISIBILITY_READ_WRITE_VALUES`.

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

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

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

        Returns
        -------
        RetrieveOrderCustomAttributeDefinitionResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.orders.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,
    ) -> UpdateOrderCustomAttributeDefinitionResponse:
        """
        Updates an order-related custom attribute definition for a Square seller account.

        Only the definition owner can update a custom attribute definition. Note that sellers can view all custom attributes in exported customer data, including those set to `VISIBILITY_HIDDEN`.

        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. This endpoint supports sparse updates,
            so only new or changed fields need to be included in the request.  For more information, see
            [Updatable definition fields](https://developer.squareup.com/docs/orders-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
        -------
        UpdateOrderCustomAttributeDefinitionResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.orders.custom_attribute_definitions.update(
            key="key",
            custom_attribute_definition={
                "key": "cover-count",
                "visibility": "VISIBILITY_READ_ONLY",
                "version": 1,
            },
            idempotency_key="IDEMPOTENCY_KEY",
        )
        """
        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
    ) -> DeleteOrderCustomAttributeDefinitionResponse:
        """
        Deletes an order-related [custom attribute definition](entity:CustomAttributeDefinition) from a Square seller account.

        Only the definition owner can delete a custom attribute definition.

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

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

        Returns
        -------
        DeleteOrderCustomAttributeDefinitionResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.orders.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,
        *,
        visibility_filter: typing.Optional[VisibilityFilter] = None,
        cursor: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[CustomAttributeDefinition]:
        """
        Lists the order-related [custom attribute definitions](entity:CustomAttributeDefinition) that belong to a Square seller account.

        When all response pages are retrieved, the results include all custom attribute definitions
        that are visible to the requesting application, including those that are created by other
        applications and set to `VISIBILITY_READ_ONLY` or `VISIBILITY_READ_WRITE_VALUES`. Note that
        seller-defined custom attributes (also known as custom fields) are always set to `VISIBILITY_READ_WRITE_VALUES`.

        Parameters
        ----------
        visibility_filter : typing.Optional[VisibilityFilter]
            Requests that all of the custom attributes be returned, or only those that are read-only or read-write.

        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/working-with-apis/pagination).

        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/working-with-apis/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.orders.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/orders/custom-attribute-definitions",
            method="GET",
            params={
                "visibility_filter": visibility_filter,
                "cursor": cursor,
                "limit": limit,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListOrderCustomAttributeDefinitionsResponse,
                    construct_type(
                        type_=ListOrderCustomAttributeDefinitionsResponse,  # 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(
                    visibility_filter=visibility_filter,
                    cursor=_parsed_next,
                    limit=limit,
                    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,
    ) -> CreateOrderCustomAttributeDefinitionResponse:
        """
        Creates an order-related custom attribute definition.  Use this endpoint to
        define a custom attribute that can be associated with orders.

        After creating a custom attribute definition, you can set the custom attribute for orders
        in the Square seller account.

        Parameters
        ----------
        custom_attribute_definition : CustomAttributeDefinitionParams
            The custom attribute definition to create. Note the following:
            - 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, including supported values and constraints, see
            [Specifying the schema](https://developer.squareup.com/docs/customer-custom-attributes-api/custom-attribute-definitions#specify-schema).
            - If provided, `name` must be unique (case-sensitive) across all visible customer-related custom attribute definitions for the seller.
            - All custom attributes are visible in exported customer data, including those set to `VISIBILITY_HIDDEN`.

        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
        -------
        CreateOrderCustomAttributeDefinitionResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.orders.custom_attribute_definitions.create(
                custom_attribute_definition={
                    "key": "cover-count",
                    "schema": {
                        "ref": "https://developer-production-s.squarecdn.com/schemas/v1/common.json#squareup.common.Number"
                    },
                    "name": "Cover count",
                    "description": "The number of people seated at a table",
                    "visibility": "VISIBILITY_READ_WRITE_VALUES",
                },
                idempotency_key="IDEMPOTENCY_KEY",
            )


        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
    ) -> RetrieveOrderCustomAttributeDefinitionResponse:
        """
        Retrieves an order-related [custom attribute definition](entity:CustomAttributeDefinition) from a Square seller account.

        To retrieve a custom attribute definition created by another application, the `visibility`
        setting must be `VISIBILITY_READ_ONLY` or `VISIBILITY_READ_WRITE_VALUES`. Note that seller-defined custom attributes
        (also known as custom fields) are always set to `VISIBILITY_READ_WRITE_VALUES`.

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

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

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

        Returns
        -------
        RetrieveOrderCustomAttributeDefinitionResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.orders.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,
    ) -> UpdateOrderCustomAttributeDefinitionResponse:
        """
        Updates an order-related custom attribute definition for a Square seller account.

        Only the definition owner can update a custom attribute definition. Note that sellers can view all custom attributes in exported customer data, including those set to `VISIBILITY_HIDDEN`.

        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. This endpoint supports sparse updates,
            so only new or changed fields need to be included in the request.  For more information, see
            [Updatable definition fields](https://developer.squareup.com/docs/orders-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
        -------
        UpdateOrderCustomAttributeDefinitionResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.orders.custom_attribute_definitions.update(
                key="key",
                custom_attribute_definition={
                    "key": "cover-count",
                    "visibility": "VISIBILITY_READ_ONLY",
                    "version": 1,
                },
                idempotency_key="IDEMPOTENCY_KEY",
            )


        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
    ) -> DeleteOrderCustomAttributeDefinitionResponse:
        """
        Deletes an order-related [custom attribute definition](entity:CustomAttributeDefinition) from a Square seller account.

        Only the definition owner can delete a custom attribute definition.

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

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

        Returns
        -------
        DeleteOrderCustomAttributeDefinitionResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


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


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