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

import typing
from ..core.client_wrapper import SyncClientWrapper
from .raw_client import RawBookingsClient
from .custom_attribute_definitions.client import CustomAttributeDefinitionsClient
from .custom_attributes.client import CustomAttributesClient
from .location_profiles.client import LocationProfilesClient
from .team_member_profiles.client import TeamMemberProfilesClient
from ..core.request_options import RequestOptions
from ..core.pagination import SyncPager
from ..types.booking import Booking
from ..types.list_bookings_response import ListBookingsResponse
from ..core.unchecked_base_model import construct_type
from json.decoder import JSONDecodeError
from ..core.api_error import ApiError
from ..requests.booking import BookingParams
from ..types.create_booking_response import CreateBookingResponse
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 ..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 .raw_client import AsyncRawBookingsClient
from .custom_attribute_definitions.client import AsyncCustomAttributeDefinitionsClient
from .custom_attributes.client import AsyncCustomAttributesClient
from .location_profiles.client import AsyncLocationProfilesClient
from .team_member_profiles.client import AsyncTeamMemberProfilesClient
from ..core.pagination import AsyncPager

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


class BookingsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawBookingsClient(client_wrapper=client_wrapper)
        self.custom_attribute_definitions = CustomAttributeDefinitionsClient(client_wrapper=client_wrapper)

        self.custom_attributes = CustomAttributesClient(client_wrapper=client_wrapper)

        self.location_profiles = LocationProfilesClient(client_wrapper=client_wrapper)

        self.team_member_profiles = TeamMemberProfilesClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        RawBookingsClient
        """
        return self._raw_client

    def list(
        self,
        *,
        limit: typing.Optional[int] = None,
        cursor: typing.Optional[str] = None,
        customer_id: typing.Optional[str] = None,
        team_member_id: typing.Optional[str] = None,
        location_id: typing.Optional[str] = None,
        start_at_min: typing.Optional[str] = None,
        start_at_max: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[Booking]:
        """
        Retrieve a collection of bookings.

        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 per page to return in a paged response.

        cursor : typing.Optional[str]
            The pagination cursor from the preceding response to return the next page of the results. Do not set this when retrieving the first page of the results.

        customer_id : typing.Optional[str]
            The [customer](entity:Customer) for whom to retrieve bookings. If this is not set, bookings for all customers are retrieved.

        team_member_id : typing.Optional[str]
            The team member for whom to retrieve bookings. If this is not set, bookings of all members are retrieved.

        location_id : typing.Optional[str]
            The location for which to retrieve bookings. If this is not set, all locations' bookings are retrieved.

        start_at_min : typing.Optional[str]
            The RFC 3339 timestamp specifying the earliest of the start time. If this is not set, the current time is used.

        start_at_max : typing.Optional[str]
            The RFC 3339 timestamp specifying the latest of the start time. If this is not set, the time of 31 days after `start_at_min` is used.

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

        Returns
        -------
        SyncPager[Booking]
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        response = client.bookings.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",
            method="GET",
            params={
                "limit": limit,
                "cursor": cursor,
                "customer_id": customer_id,
                "team_member_id": team_member_id,
                "location_id": location_id,
                "start_at_min": start_at_min,
                "start_at_max": start_at_max,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListBookingsResponse,
                    construct_type(
                        type_=ListBookingsResponse,  # 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,
                    customer_id=customer_id,
                    team_member_id=team_member_id,
                    location_id=location_id,
                    start_at_min=start_at_min,
                    start_at_max=start_at_max,
                    request_options=request_options,
                )
                _items = _parsed_response.bookings
                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,
        *,
        booking: BookingParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> 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
        -------
        CreateBookingResponse
            Success

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

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

    def search_availability(
        self, *, query: SearchAvailabilityQueryParams, request_options: typing.Optional[RequestOptions] = None
    ) -> 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
        -------
        SearchAvailabilityResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.bookings.search_availability(
            query={"filter": {"start_at_range": {}}},
        )
        """
        response = self._raw_client.search_availability(query=query, request_options=request_options)
        return response.data

    def bulk_retrieve_bookings(
        self, *, booking_ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
    ) -> 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
        -------
        BulkRetrieveBookingsResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.bookings.bulk_retrieve_bookings(
            booking_ids=["booking_ids"],
        )
        """
        response = self._raw_client.bulk_retrieve_bookings(booking_ids=booking_ids, request_options=request_options)
        return response.data

    def get_business_profile(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> GetBusinessBookingProfileResponse:
        """
        Retrieves a seller's booking profile.

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

        Returns
        -------
        GetBusinessBookingProfileResponse
            Success

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

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

    def retrieve_location_booking_profile(
        self, location_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> 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
        -------
        RetrieveLocationBookingProfileResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.bookings.retrieve_location_booking_profile(
            location_id="location_id",
        )
        """
        response = self._raw_client.retrieve_location_booking_profile(location_id, request_options=request_options)
        return response.data

    def bulk_retrieve_team_member_booking_profiles(
        self, *, team_member_ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
    ) -> 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
        -------
        BulkRetrieveTeamMemberBookingProfilesResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.bookings.bulk_retrieve_team_member_booking_profiles(
            team_member_ids=["team_member_ids"],
        )
        """
        response = self._raw_client.bulk_retrieve_team_member_booking_profiles(
            team_member_ids=team_member_ids, request_options=request_options
        )
        return response.data

    def get(self, booking_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> 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
        -------
        GetBookingResponse
            Success

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

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

    def update(
        self,
        booking_id: str,
        *,
        booking: BookingParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> 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
        -------
        UpdateBookingResponse
            Success

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

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

    def cancel(
        self,
        booking_id: str,
        *,
        idempotency_key: typing.Optional[str] = OMIT,
        booking_version: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> 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
        -------
        CancelBookingResponse
            Success

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

        client = Square(
            token="YOUR_TOKEN",
        )
        client.bookings.cancel(
            booking_id="booking_id",
        )
        """
        response = self._raw_client.cancel(
            booking_id,
            idempotency_key=idempotency_key,
            booking_version=booking_version,
            request_options=request_options,
        )
        return response.data


class AsyncBookingsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawBookingsClient(client_wrapper=client_wrapper)
        self.custom_attribute_definitions = AsyncCustomAttributeDefinitionsClient(client_wrapper=client_wrapper)

        self.custom_attributes = AsyncCustomAttributesClient(client_wrapper=client_wrapper)

        self.location_profiles = AsyncLocationProfilesClient(client_wrapper=client_wrapper)

        self.team_member_profiles = AsyncTeamMemberProfilesClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        AsyncRawBookingsClient
        """
        return self._raw_client

    async def list(
        self,
        *,
        limit: typing.Optional[int] = None,
        cursor: typing.Optional[str] = None,
        customer_id: typing.Optional[str] = None,
        team_member_id: typing.Optional[str] = None,
        location_id: typing.Optional[str] = None,
        start_at_min: typing.Optional[str] = None,
        start_at_max: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[Booking]:
        """
        Retrieve a collection of bookings.

        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 per page to return in a paged response.

        cursor : typing.Optional[str]
            The pagination cursor from the preceding response to return the next page of the results. Do not set this when retrieving the first page of the results.

        customer_id : typing.Optional[str]
            The [customer](entity:Customer) for whom to retrieve bookings. If this is not set, bookings for all customers are retrieved.

        team_member_id : typing.Optional[str]
            The team member for whom to retrieve bookings. If this is not set, bookings of all members are retrieved.

        location_id : typing.Optional[str]
            The location for which to retrieve bookings. If this is not set, all locations' bookings are retrieved.

        start_at_min : typing.Optional[str]
            The RFC 3339 timestamp specifying the earliest of the start time. If this is not set, the current time is used.

        start_at_max : typing.Optional[str]
            The RFC 3339 timestamp specifying the latest of the start time. If this is not set, the time of 31 days after `start_at_min` is used.

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

        Returns
        -------
        AsyncPager[Booking]
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            response = await client.bookings.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",
            method="GET",
            params={
                "limit": limit,
                "cursor": cursor,
                "customer_id": customer_id,
                "team_member_id": team_member_id,
                "location_id": location_id,
                "start_at_min": start_at_min,
                "start_at_max": start_at_max,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListBookingsResponse,
                    construct_type(
                        type_=ListBookingsResponse,  # 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,
                    customer_id=customer_id,
                    team_member_id=team_member_id,
                    location_id=location_id,
                    start_at_min=start_at_min,
                    start_at_max=start_at_max,
                    request_options=request_options,
                )
                _items = _parsed_response.bookings
                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,
        *,
        booking: BookingParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> 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
        -------
        CreateBookingResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


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


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

    async def search_availability(
        self, *, query: SearchAvailabilityQueryParams, request_options: typing.Optional[RequestOptions] = None
    ) -> 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
        -------
        SearchAvailabilityResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.bookings.search_availability(
                query={"filter": {"start_at_range": {}}},
            )


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

    async def bulk_retrieve_bookings(
        self, *, booking_ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
    ) -> 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
        -------
        BulkRetrieveBookingsResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.bookings.bulk_retrieve_bookings(
                booking_ids=["booking_ids"],
            )


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

    async def get_business_profile(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> GetBusinessBookingProfileResponse:
        """
        Retrieves a seller's booking profile.

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

        Returns
        -------
        GetBusinessBookingProfileResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.bookings.get_business_profile()


        asyncio.run(main())
        """
        response = await self._raw_client.get_business_profile(request_options=request_options)
        return response.data

    async def retrieve_location_booking_profile(
        self, location_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> 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
        -------
        RetrieveLocationBookingProfileResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.bookings.retrieve_location_booking_profile(
                location_id="location_id",
            )


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

    async def bulk_retrieve_team_member_booking_profiles(
        self, *, team_member_ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
    ) -> 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
        -------
        BulkRetrieveTeamMemberBookingProfilesResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.bookings.bulk_retrieve_team_member_booking_profiles(
                team_member_ids=["team_member_ids"],
            )


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

    async def get(
        self, booking_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> 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
        -------
        GetBookingResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


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


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

    async def update(
        self,
        booking_id: str,
        *,
        booking: BookingParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> 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
        -------
        UpdateBookingResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.bookings.update(
                booking_id="booking_id",
                booking={},
            )


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

    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,
    ) -> 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
        -------
        CancelBookingResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.bookings.cancel(
                booking_id="booking_id",
            )


        asyncio.run(main())
        """
        response = await self._raw_client.cancel(
            booking_id,
            idempotency_key=idempotency_key,
            booking_version=booking_version,
            request_options=request_options,
        )
        return response.data
