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

import typing
from ...core.client_wrapper import SyncClientWrapper
from ...requests.custom_attribute_definition import CustomAttributeDefinitionParams
from ...core.request_options import RequestOptions
from ...core.http_response import HttpResponse
from ...types.create_location_custom_attribute_definition_response import (
    CreateLocationCustomAttributeDefinitionResponse,
)
from ...core.serialization import convert_and_respect_annotation_metadata
from ...core.unchecked_base_model import construct_type
from json.decoder import JSONDecodeError
from ...core.api_error import ApiError
from ...types.retrieve_location_custom_attribute_definition_response import (
    RetrieveLocationCustomAttributeDefinitionResponse,
)
from ...core.jsonable_encoder import jsonable_encoder
from ...types.update_location_custom_attribute_definition_response import (
    UpdateLocationCustomAttributeDefinitionResponse,
)
from ...types.delete_location_custom_attribute_definition_response import (
    DeleteLocationCustomAttributeDefinitionResponse,
)
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 RawCustomAttributeDefinitionsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def create(
        self,
        *,
        custom_attribute_definition: CustomAttributeDefinitionParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[CreateLocationCustomAttributeDefinitionResponse]:
        """
        Creates a location-related [custom attribute definition](entity:CustomAttributeDefinition) for a Square seller account.
        Use this endpoint to define a custom attribute that can be associated with locations.
        A custom attribute definition specifies the `key`, `visibility`, `schema`, and other properties
        for a custom attribute. After the definition is created, you can call
        [UpsertLocationCustomAttribute](api-endpoint:LocationCustomAttributes-UpsertLocationCustomAttribute) or
        [BulkUpsertLocationCustomAttributes](api-endpoint:LocationCustomAttributes-BulkUpsertLocationCustomAttributes)
        to set the custom attribute for locations.

        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
            [Supported data types](https://developer.squareup.com/docs/devtools/customattributes/overview#supported-data-types).
            - `name` is required unless `visibility` is 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
        -------
        HttpResponse[CreateLocationCustomAttributeDefinitionResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/locations/custom-attribute-definitions",
            method="POST",
            json={
                "custom_attribute_definition": convert_and_respect_annotation_metadata(
                    object_=custom_attribute_definition, annotation=CustomAttributeDefinitionParams, direction="write"
                ),
                "idempotency_key": idempotency_key,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateLocationCustomAttributeDefinitionResponse,
                    construct_type(
                        type_=CreateLocationCustomAttributeDefinitionResponse,  # 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, key: str, *, version: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[RetrieveLocationCustomAttributeDefinitionResponse]:
        """
        Retrieves a location-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`.

        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
        -------
        HttpResponse[RetrieveLocationCustomAttributeDefinitionResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/locations/custom-attribute-definitions/{jsonable_encoder(key)}",
            method="GET",
            params={
                "version": version,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    RetrieveLocationCustomAttributeDefinitionResponse,
                    construct_type(
                        type_=RetrieveLocationCustomAttributeDefinitionResponse,  # 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 update(
        self,
        key: str,
        *,
        custom_attribute_definition: CustomAttributeDefinitionParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[UpdateLocationCustomAttributeDefinitionResponse]:
        """
        Updates a location-related [custom attribute definition](entity:CustomAttributeDefinition) for a Square seller account.
        Use this endpoint to update the following fields: `name`, `description`, `visibility`, or the
        `schema` for a `Selection` data type.
        Only the definition owner can update a custom attribute definition.

        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.
            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
            [Update a location custom attribute definition](https://developer.squareup.com/docs/location-custom-attributes-api/custom-attribute-definitions#update-custom-attribute-definition).
            To enable [optimistic concurrency](https://developer.squareup.com/docs/build-basics/common-api-patterns/optimistic-concurrency)
            control, specify the current version of the custom attribute definition.
            If this is not important for your application, `version` can be set to -1.

        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
        -------
        HttpResponse[UpdateLocationCustomAttributeDefinitionResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/locations/custom-attribute-definitions/{jsonable_encoder(key)}",
            method="PUT",
            json={
                "custom_attribute_definition": convert_and_respect_annotation_metadata(
                    object_=custom_attribute_definition, annotation=CustomAttributeDefinitionParams, direction="write"
                ),
                "idempotency_key": idempotency_key,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpdateLocationCustomAttributeDefinitionResponse,
                    construct_type(
                        type_=UpdateLocationCustomAttributeDefinitionResponse,  # 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 delete(
        self, key: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[DeleteLocationCustomAttributeDefinitionResponse]:
        """
        Deletes a location-related [custom attribute definition](entity:CustomAttributeDefinition) from a Square seller account.
        Deleting a custom attribute definition also deletes the corresponding custom attribute from
        all locations.
        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
        -------
        HttpResponse[DeleteLocationCustomAttributeDefinitionResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/locations/custom-attribute-definitions/{jsonable_encoder(key)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DeleteLocationCustomAttributeDefinitionResponse,
                    construct_type(
                        type_=DeleteLocationCustomAttributeDefinitionResponse,  # 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 AsyncRawCustomAttributeDefinitionsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def create(
        self,
        *,
        custom_attribute_definition: CustomAttributeDefinitionParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[CreateLocationCustomAttributeDefinitionResponse]:
        """
        Creates a location-related [custom attribute definition](entity:CustomAttributeDefinition) for a Square seller account.
        Use this endpoint to define a custom attribute that can be associated with locations.
        A custom attribute definition specifies the `key`, `visibility`, `schema`, and other properties
        for a custom attribute. After the definition is created, you can call
        [UpsertLocationCustomAttribute](api-endpoint:LocationCustomAttributes-UpsertLocationCustomAttribute) or
        [BulkUpsertLocationCustomAttributes](api-endpoint:LocationCustomAttributes-BulkUpsertLocationCustomAttributes)
        to set the custom attribute for locations.

        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
            [Supported data types](https://developer.squareup.com/docs/devtools/customattributes/overview#supported-data-types).
            - `name` is required unless `visibility` is 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
        -------
        AsyncHttpResponse[CreateLocationCustomAttributeDefinitionResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/locations/custom-attribute-definitions",
            method="POST",
            json={
                "custom_attribute_definition": convert_and_respect_annotation_metadata(
                    object_=custom_attribute_definition, annotation=CustomAttributeDefinitionParams, direction="write"
                ),
                "idempotency_key": idempotency_key,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateLocationCustomAttributeDefinitionResponse,
                    construct_type(
                        type_=CreateLocationCustomAttributeDefinitionResponse,  # 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, key: str, *, version: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[RetrieveLocationCustomAttributeDefinitionResponse]:
        """
        Retrieves a location-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`.

        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
        -------
        AsyncHttpResponse[RetrieveLocationCustomAttributeDefinitionResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/locations/custom-attribute-definitions/{jsonable_encoder(key)}",
            method="GET",
            params={
                "version": version,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    RetrieveLocationCustomAttributeDefinitionResponse,
                    construct_type(
                        type_=RetrieveLocationCustomAttributeDefinitionResponse,  # 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 update(
        self,
        key: str,
        *,
        custom_attribute_definition: CustomAttributeDefinitionParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[UpdateLocationCustomAttributeDefinitionResponse]:
        """
        Updates a location-related [custom attribute definition](entity:CustomAttributeDefinition) for a Square seller account.
        Use this endpoint to update the following fields: `name`, `description`, `visibility`, or the
        `schema` for a `Selection` data type.
        Only the definition owner can update a custom attribute definition.

        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.
            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
            [Update a location custom attribute definition](https://developer.squareup.com/docs/location-custom-attributes-api/custom-attribute-definitions#update-custom-attribute-definition).
            To enable [optimistic concurrency](https://developer.squareup.com/docs/build-basics/common-api-patterns/optimistic-concurrency)
            control, specify the current version of the custom attribute definition.
            If this is not important for your application, `version` can be set to -1.

        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
        -------
        AsyncHttpResponse[UpdateLocationCustomAttributeDefinitionResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/locations/custom-attribute-definitions/{jsonable_encoder(key)}",
            method="PUT",
            json={
                "custom_attribute_definition": convert_and_respect_annotation_metadata(
                    object_=custom_attribute_definition, annotation=CustomAttributeDefinitionParams, direction="write"
                ),
                "idempotency_key": idempotency_key,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpdateLocationCustomAttributeDefinitionResponse,
                    construct_type(
                        type_=UpdateLocationCustomAttributeDefinitionResponse,  # 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 delete(
        self, key: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[DeleteLocationCustomAttributeDefinitionResponse]:
        """
        Deletes a location-related [custom attribute definition](entity:CustomAttributeDefinition) from a Square seller account.
        Deleting a custom attribute definition also deletes the corresponding custom attribute from
        all locations.
        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
        -------
        AsyncHttpResponse[DeleteLocationCustomAttributeDefinitionResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/locations/custom-attribute-definitions/{jsonable_encoder(key)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DeleteLocationCustomAttributeDefinitionResponse,
                    construct_type(
                        type_=DeleteLocationCustomAttributeDefinitionResponse,  # 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)
