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

import typing
from ..core.client_wrapper import SyncClientWrapper
from ..requests.booking import BookingParams
from ..core.request_options import RequestOptions
from ..core.http_response import HttpResponse
from ..types.create_booking_response import CreateBookingResponse
from ..core.serialization import convert_and_respect_annotation_metadata
from ..core.unchecked_base_model import construct_type
from json.decoder import JSONDecodeError
from ..core.api_error import ApiError
from ..requests.search_availability_query import SearchAvailabilityQueryParams
from ..types.search_availability_response import SearchAvailabilityResponse
from ..types.bulk_retrieve_bookings_response import BulkRetrieveBookingsResponse
from ..types.get_business_booking_profile_response import GetBusinessBookingProfileResponse
from ..types.retrieve_location_booking_profile_response import RetrieveLocationBookingProfileResponse
from ..core.jsonable_encoder import jsonable_encoder
from ..types.bulk_retrieve_team_member_booking_profiles_response import BulkRetrieveTeamMemberBookingProfilesResponse
from ..types.get_booking_response import GetBookingResponse
from ..types.update_booking_response import UpdateBookingResponse
from ..types.cancel_booking_response import CancelBookingResponse
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 RawBookingsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def create(
        self,
        *,
        booking: BookingParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[CreateBookingResponse]:
        """
        Creates a booking.

        The required input must include the following:
        - `Booking.location_id`
        - `Booking.start_at`
        - `Booking.AppointmentSegment.team_member_id`
        - `Booking.AppointmentSegment.service_variation_id`
        - `Booking.AppointmentSegment.service_variation_version`

        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
        ----------
        booking : BookingParams
            The details of the booking to be created.

        idempotency_key : typing.Optional[str]
            A unique key to make this request an idempotent operation.

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

        Returns
        -------
        HttpResponse[CreateBookingResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/bookings",
            method="POST",
            json={
                "idempotency_key": idempotency_key,
                "booking": convert_and_respect_annotation_metadata(
                    object_=booking, annotation=BookingParams, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateBookingResponse,
                    construct_type(
                        type_=CreateBookingResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def search_availability(
        self, *, query: SearchAvailabilityQueryParams, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[SearchAvailabilityResponse]:
        """
        Searches for availabilities for booking.

        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
        ----------
        query : SearchAvailabilityQueryParams
            Query conditions used to filter buyer-accessible booking availabilities.

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

        Returns
        -------
        HttpResponse[SearchAvailabilityResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/bookings/availability/search",
            method="POST",
            json={
                "query": convert_and_respect_annotation_metadata(
                    object_=query, annotation=SearchAvailabilityQueryParams, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SearchAvailabilityResponse,
                    construct_type(
                        type_=SearchAvailabilityResponse,  # 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 bulk_retrieve_bookings(
        self, *, booking_ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[BulkRetrieveBookingsResponse]:
        """
        Bulk-Retrieves a list of bookings by booking IDs.

        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
        ----------
        booking_ids : typing.Sequence[str]
            A non-empty list of [Booking](entity:Booking) IDs specifying bookings to retrieve.

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

        Returns
        -------
        HttpResponse[BulkRetrieveBookingsResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/bookings/bulk-retrieve",
            method="POST",
            json={
                "booking_ids": booking_ids,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    BulkRetrieveBookingsResponse,
                    construct_type(
                        type_=BulkRetrieveBookingsResponse,  # 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_business_profile(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[GetBusinessBookingProfileResponse]:
        """
        Retrieves a seller's booking profile.

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

        Returns
        -------
        HttpResponse[GetBusinessBookingProfileResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/bookings/business-booking-profile",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetBusinessBookingProfileResponse,
                    construct_type(
                        type_=GetBusinessBookingProfileResponse,  # 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 retrieve_location_booking_profile(
        self, location_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[RetrieveLocationBookingProfileResponse]:
        """
        Retrieves a seller's location booking profile.

        Parameters
        ----------
        location_id : str
            The ID of the location to retrieve the booking profile.

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

        Returns
        -------
        HttpResponse[RetrieveLocationBookingProfileResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/bookings/location-booking-profiles/{jsonable_encoder(location_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    RetrieveLocationBookingProfileResponse,
                    construct_type(
                        type_=RetrieveLocationBookingProfileResponse,  # 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 bulk_retrieve_team_member_booking_profiles(
        self, *, team_member_ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[BulkRetrieveTeamMemberBookingProfilesResponse]:
        """
        Retrieves one or more team members' booking profiles.

        Parameters
        ----------
        team_member_ids : typing.Sequence[str]
            A non-empty list of IDs of team members whose booking profiles you want to retrieve.

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

        Returns
        -------
        HttpResponse[BulkRetrieveTeamMemberBookingProfilesResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/bookings/team-member-booking-profiles/bulk-retrieve",
            method="POST",
            json={
                "team_member_ids": team_member_ids,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    BulkRetrieveTeamMemberBookingProfilesResponse,
                    construct_type(
                        type_=BulkRetrieveTeamMemberBookingProfilesResponse,  # 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, booking_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[GetBookingResponse]:
        """
        Retrieves a booking.

        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
        ----------
        booking_id : str
            The ID of the [Booking](entity:Booking) object representing the to-be-retrieved booking.

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

        Returns
        -------
        HttpResponse[GetBookingResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/bookings/{jsonable_encoder(booking_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetBookingResponse,
                    construct_type(
                        type_=GetBookingResponse,  # 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,
        booking_id: str,
        *,
        booking: BookingParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[UpdateBookingResponse]:
        """
        Updates a booking.

        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
        ----------
        booking_id : str
            The ID of the [Booking](entity:Booking) object representing the to-be-updated booking.

        booking : BookingParams
            The booking to be updated. Individual attributes explicitly specified here override the corresponding values of the existing booking.

        idempotency_key : typing.Optional[str]
            A unique key to make this request an idempotent operation.

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

        Returns
        -------
        HttpResponse[UpdateBookingResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/bookings/{jsonable_encoder(booking_id)}",
            method="PUT",
            json={
                "idempotency_key": idempotency_key,
                "booking": convert_and_respect_annotation_metadata(
                    object_=booking, annotation=BookingParams, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpdateBookingResponse,
                    construct_type(
                        type_=UpdateBookingResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def cancel(
        self,
        booking_id: str,
        *,
        idempotency_key: typing.Optional[str] = OMIT,
        booking_version: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[CancelBookingResponse]:
        """
        Cancels an existing booking.

        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
        ----------
        booking_id : str
            The ID of the [Booking](entity:Booking) object representing the to-be-cancelled booking.

        idempotency_key : typing.Optional[str]
            A unique key to make this request an idempotent operation.

        booking_version : typing.Optional[int]
            The revision number for the booking used for optimistic concurrency.

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

        Returns
        -------
        HttpResponse[CancelBookingResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/bookings/{jsonable_encoder(booking_id)}/cancel",
            method="POST",
            json={
                "idempotency_key": idempotency_key,
                "booking_version": booking_version,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CancelBookingResponse,
                    construct_type(
                        type_=CancelBookingResponse,  # 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 AsyncRawBookingsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def create(
        self,
        *,
        booking: BookingParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[CreateBookingResponse]:
        """
        Creates a booking.

        The required input must include the following:
        - `Booking.location_id`
        - `Booking.start_at`
        - `Booking.AppointmentSegment.team_member_id`
        - `Booking.AppointmentSegment.service_variation_id`
        - `Booking.AppointmentSegment.service_variation_version`

        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
        ----------
        booking : BookingParams
            The details of the booking to be created.

        idempotency_key : typing.Optional[str]
            A unique key to make this request an idempotent operation.

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

        Returns
        -------
        AsyncHttpResponse[CreateBookingResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/bookings",
            method="POST",
            json={
                "idempotency_key": idempotency_key,
                "booking": convert_and_respect_annotation_metadata(
                    object_=booking, annotation=BookingParams, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateBookingResponse,
                    construct_type(
                        type_=CreateBookingResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def search_availability(
        self, *, query: SearchAvailabilityQueryParams, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[SearchAvailabilityResponse]:
        """
        Searches for availabilities for booking.

        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
        ----------
        query : SearchAvailabilityQueryParams
            Query conditions used to filter buyer-accessible booking availabilities.

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

        Returns
        -------
        AsyncHttpResponse[SearchAvailabilityResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/bookings/availability/search",
            method="POST",
            json={
                "query": convert_and_respect_annotation_metadata(
                    object_=query, annotation=SearchAvailabilityQueryParams, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SearchAvailabilityResponse,
                    construct_type(
                        type_=SearchAvailabilityResponse,  # 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 bulk_retrieve_bookings(
        self, *, booking_ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[BulkRetrieveBookingsResponse]:
        """
        Bulk-Retrieves a list of bookings by booking IDs.

        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
        ----------
        booking_ids : typing.Sequence[str]
            A non-empty list of [Booking](entity:Booking) IDs specifying bookings to retrieve.

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

        Returns
        -------
        AsyncHttpResponse[BulkRetrieveBookingsResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/bookings/bulk-retrieve",
            method="POST",
            json={
                "booking_ids": booking_ids,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    BulkRetrieveBookingsResponse,
                    construct_type(
                        type_=BulkRetrieveBookingsResponse,  # 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_business_profile(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[GetBusinessBookingProfileResponse]:
        """
        Retrieves a seller's booking profile.

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

        Returns
        -------
        AsyncHttpResponse[GetBusinessBookingProfileResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/bookings/business-booking-profile",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetBusinessBookingProfileResponse,
                    construct_type(
                        type_=GetBusinessBookingProfileResponse,  # 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 retrieve_location_booking_profile(
        self, location_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[RetrieveLocationBookingProfileResponse]:
        """
        Retrieves a seller's location booking profile.

        Parameters
        ----------
        location_id : str
            The ID of the location to retrieve the booking profile.

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

        Returns
        -------
        AsyncHttpResponse[RetrieveLocationBookingProfileResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/bookings/location-booking-profiles/{jsonable_encoder(location_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    RetrieveLocationBookingProfileResponse,
                    construct_type(
                        type_=RetrieveLocationBookingProfileResponse,  # 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 bulk_retrieve_team_member_booking_profiles(
        self, *, team_member_ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[BulkRetrieveTeamMemberBookingProfilesResponse]:
        """
        Retrieves one or more team members' booking profiles.

        Parameters
        ----------
        team_member_ids : typing.Sequence[str]
            A non-empty list of IDs of team members whose booking profiles you want to retrieve.

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

        Returns
        -------
        AsyncHttpResponse[BulkRetrieveTeamMemberBookingProfilesResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/bookings/team-member-booking-profiles/bulk-retrieve",
            method="POST",
            json={
                "team_member_ids": team_member_ids,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    BulkRetrieveTeamMemberBookingProfilesResponse,
                    construct_type(
                        type_=BulkRetrieveTeamMemberBookingProfilesResponse,  # 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, booking_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[GetBookingResponse]:
        """
        Retrieves a booking.

        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
        ----------
        booking_id : str
            The ID of the [Booking](entity:Booking) object representing the to-be-retrieved booking.

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

        Returns
        -------
        AsyncHttpResponse[GetBookingResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/bookings/{jsonable_encoder(booking_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetBookingResponse,
                    construct_type(
                        type_=GetBookingResponse,  # 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,
        booking_id: str,
        *,
        booking: BookingParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[UpdateBookingResponse]:
        """
        Updates a booking.

        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
        ----------
        booking_id : str
            The ID of the [Booking](entity:Booking) object representing the to-be-updated booking.

        booking : BookingParams
            The booking to be updated. Individual attributes explicitly specified here override the corresponding values of the existing booking.

        idempotency_key : typing.Optional[str]
            A unique key to make this request an idempotent operation.

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

        Returns
        -------
        AsyncHttpResponse[UpdateBookingResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/bookings/{jsonable_encoder(booking_id)}",
            method="PUT",
            json={
                "idempotency_key": idempotency_key,
                "booking": convert_and_respect_annotation_metadata(
                    object_=booking, annotation=BookingParams, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpdateBookingResponse,
                    construct_type(
                        type_=UpdateBookingResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def cancel(
        self,
        booking_id: str,
        *,
        idempotency_key: typing.Optional[str] = OMIT,
        booking_version: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[CancelBookingResponse]:
        """
        Cancels an existing booking.

        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
        ----------
        booking_id : str
            The ID of the [Booking](entity:Booking) object representing the to-be-cancelled booking.

        idempotency_key : typing.Optional[str]
            A unique key to make this request an idempotent operation.

        booking_version : typing.Optional[int]
            The revision number for the booking used for optimistic concurrency.

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

        Returns
        -------
        AsyncHttpResponse[CancelBookingResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/bookings/{jsonable_encoder(booking_id)}/cancel",
            method="POST",
            json={
                "idempotency_key": idempotency_key,
                "booking_version": booking_version,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CancelBookingResponse,
                    construct_type(
                        type_=CancelBookingResponse,  # 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)
