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

import datetime as dt
import typing
from json.decoder import JSONDecodeError

from .......core.api_error import ApiError
from .......core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from .......core.datetime_utils import serialize_datetime
from .......core.http_response import AsyncHttpResponse, HttpResponse
from .......core.jsonable_encoder import jsonable_encoder
from .......core.pydantic_utilities import parse_obj_as
from .......core.request_options import RequestOptions
from ....common.errors.bad_request_error import BadRequestError
from ....common.errors.not_found_error import NotFoundError
from ....common.errors.version_conflict_error import VersionConflictError
from ....common.types.appointment_id import AppointmentId
from ....common.types.error_base_4_xx import ErrorBase4Xx
from ....common.types.filter_query_string import FilterQueryString
from ....common.types.page_token import PageToken
from ....common.types.sort_direction import SortDirection
from ....common.types.version_conflict_error_body import VersionConflictErrorBody
from ....lists.resources.v_1.types.sort_field_string import SortFieldString
from .types.appointment import Appointment
from .types.mutable_appointment import MutableAppointment
from .types.visits_page import VisitsPage

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


class RawV1Client:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def create(
        self, *, request: MutableAppointment, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[Appointment]:
        """
        Adds an appointment.  VersionConflictError is returned when the placer_appointment_id is already in use.

        Parameters
        ----------
        request : MutableAppointment

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

        Returns
        -------
        HttpResponse[Appointment]
        """
        _response = self._client_wrapper.httpx_client.request(
            "appointments/v1",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="POST",
            json=request,
            request_options=request_options,
            omit=OMIT,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        if 200 <= _response.status_code < 300:
            _data = typing.cast(
                Appointment,
                parse_obj_as(
                    type_=Appointment,  # type: ignore
                    object_=_response_json,
                ),
            )
            return HttpResponse(response=_response, data=_data)
        if "errorName" in _response_json:
            if _response_json["errorName"] == "VersionConflictError":
                raise VersionConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        VersionConflictErrorBody,
                        parse_obj_as(
                            type_=VersionConflictErrorBody,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    ),
                )
            if _response_json["errorName"] == "NotFoundError":
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorBase4Xx,
                        parse_obj_as(
                            type_=ErrorBase4Xx,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    ),
                )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_visits(
        self,
        *,
        page_token: typing.Optional[PageToken] = None,
        limit: typing.Optional[int] = None,
        sort_field: typing.Optional[SortFieldString] = None,
        sort_direction: typing.Optional[SortDirection] = None,
        filters: typing.Optional[FilterQueryString] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[VisitsPage]:
        """
        Gets all Visits within a given time range. The return list is ordered by start_time ascending.

        **IMPORTANT:** This endpoint requires a date filter on `appointment.startTimestamp` to ensure acceptable query performance.
        Without date filtering, the query can take 50+ seconds on large datasets due to grouping and aggregation operations.

        Example filters:
        - `appointment.startTimestamp|gt|2024-01-01` - appointments after January 1, 2024
        - `appointment.startTimestamp|eq|2024-12-08` - appointments on December 8, 2024
        - `appointment.startTimestamp|lt|2024-12-31` - appointments before December 31, 2024

        You can combine the date filter with other filters using commas:
        - `appointment.startTimestamp|gt|2024-01-01,appointment.status|eq|PENDING`

        Parameters
        ----------
        page_token : typing.Optional[PageToken]

        limit : typing.Optional[int]

        sort_field : typing.Optional[SortFieldString]
            Defaults to appointment.start_time.

        sort_direction : typing.Optional[SortDirection]
            Defaults to ascending.

        filters : typing.Optional[FilterQueryString]
            **Required:** Must include a date filter on appointment.startTimestamp (using gt, lt, or eq operators).
            Example: appointment.startTimestamp|gt|2024-01-01

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

        Returns
        -------
        HttpResponse[VisitsPage]
        """
        _response = self._client_wrapper.httpx_client.request(
            "appointments/v1/visits",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="GET",
            params={
                "page_token": page_token,
                "limit": limit,
                "sort_field": sort_field,
                "sort_direction": sort_direction,
                "filters": filters,
            },
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        if 200 <= _response.status_code < 300:
            _data = typing.cast(
                VisitsPage,
                parse_obj_as(
                    type_=VisitsPage,  # type: ignore
                    object_=_response_json,
                ),
            )
            return HttpResponse(response=_response, data=_data)
        if "errorName" in _response_json:
            if _response_json["errorName"] == "BadRequestError":
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorBase4Xx,
                        parse_obj_as(
                            type_=ErrorBase4Xx,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    ),
                )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get(
        self, id: AppointmentId, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[Appointment]:
        """
        Gets an appointment.

        Parameters
        ----------
        id : AppointmentId

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

        Returns
        -------
        HttpResponse[Appointment]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"appointments/v1/{jsonable_encoder(id)}",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="GET",
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        if 200 <= _response.status_code < 300:
            _data = typing.cast(
                Appointment,
                parse_obj_as(
                    type_=Appointment,  # type: ignore
                    object_=_response_json,
                ),
            )
            return HttpResponse(response=_response, data=_data)
        if "errorName" in _response_json:
            if _response_json["errorName"] == "NotFoundError":
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorBase4Xx,
                        parse_obj_as(
                            type_=ErrorBase4Xx,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    ),
                )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_history(
        self, id: AppointmentId, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[typing.List[Appointment]]:
        """
        Gets an appointment along with it's full history.  The return list is ordered by version ascending.

        Parameters
        ----------
        id : AppointmentId

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

        Returns
        -------
        HttpResponse[typing.List[Appointment]]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"appointments/v1/{jsonable_encoder(id)}/history",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="GET",
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        if 200 <= _response.status_code < 300:
            _data = typing.cast(
                typing.List[Appointment],
                parse_obj_as(
                    type_=typing.List[Appointment],  # type: ignore
                    object_=_response_json,
                ),
            )
            return HttpResponse(response=_response, data=_data)
        if "errorName" in _response_json:
            if _response_json["errorName"] == "NotFoundError":
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorBase4Xx,
                        parse_obj_as(
                            type_=ErrorBase4Xx,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    ),
                )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def update(
        self,
        id: AppointmentId,
        version: str,
        *,
        request: MutableAppointment,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[Appointment]:
        """
        Updates an appointment. The path must contain the next version number to prevent race conditions. For example, if the current version of the appointment is n, you will need to send a request to this endpoint with `/{id}/n+1` to update the appointment. Updating historic versions is not supported.

        Parameters
        ----------
        id : AppointmentId

        version : str

        request : MutableAppointment

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

        Returns
        -------
        HttpResponse[Appointment]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"appointments/v1/{jsonable_encoder(id)}/{jsonable_encoder(version)}",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="PUT",
            json=request,
            request_options=request_options,
            omit=OMIT,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        if 200 <= _response.status_code < 300:
            _data = typing.cast(
                Appointment,
                parse_obj_as(
                    type_=Appointment,  # type: ignore
                    object_=_response_json,
                ),
            )
            return HttpResponse(response=_response, data=_data)
        if "errorName" in _response_json:
            if _response_json["errorName"] == "NotFoundError":
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorBase4Xx,
                        parse_obj_as(
                            type_=ErrorBase4Xx,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    ),
                )
            if _response_json["errorName"] == "VersionConflictError":
                raise VersionConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        VersionConflictErrorBody,
                        parse_obj_as(
                            type_=VersionConflictErrorBody,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    ),
                )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def scan(
        self, *, since: dt.datetime, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[typing.List[Appointment]]:
        """
        Scans up to 100 appointment updates.  The since query parameter is inclusive, and the result list is ordered by updatedAt ascending.

        Parameters
        ----------
        since : dt.datetime

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

        Returns
        -------
        HttpResponse[typing.List[Appointment]]
        """
        _response = self._client_wrapper.httpx_client.request(
            "appointments/v1/updates/scan",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="GET",
            params={
                "since": serialize_datetime(since),
            },
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        if 200 <= _response.status_code < 300:
            _data = typing.cast(
                typing.List[Appointment],
                parse_obj_as(
                    type_=typing.List[Appointment],  # type: ignore
                    object_=_response_json,
                ),
            )
            return HttpResponse(response=_response, data=_data)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def deactivate(
        self, id: AppointmentId, version: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[None]:
        """
        Sets an appointment as deactivated.  The path must contain the most recent version to prevent race conditions.  Deactivating historic versions is not supported. Subsequent updates via PUT to the appointment will "reactivate" the appointment and set the deactivated flag to false.

        Parameters
        ----------
        id : AppointmentId

        version : str

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

        Returns
        -------
        HttpResponse[None]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"appointments/v1/{jsonable_encoder(id)}/{jsonable_encoder(version)}",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="DELETE",
            request_options=request_options,
        )
        if 200 <= _response.status_code < 300:
            return HttpResponse(response=_response, data=None)
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        if "errorName" in _response_json:
            if _response_json["errorName"] == "NotFoundError":
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorBase4Xx,
                        parse_obj_as(
                            type_=ErrorBase4Xx,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    ),
                )
            if _response_json["errorName"] == "VersionConflictError":
                raise VersionConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        VersionConflictErrorBody,
                        parse_obj_as(
                            type_=VersionConflictErrorBody,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    ),
                )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


class AsyncRawV1Client:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def create(
        self, *, request: MutableAppointment, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[Appointment]:
        """
        Adds an appointment.  VersionConflictError is returned when the placer_appointment_id is already in use.

        Parameters
        ----------
        request : MutableAppointment

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

        Returns
        -------
        AsyncHttpResponse[Appointment]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "appointments/v1",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="POST",
            json=request,
            request_options=request_options,
            omit=OMIT,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        if 200 <= _response.status_code < 300:
            _data = typing.cast(
                Appointment,
                parse_obj_as(
                    type_=Appointment,  # type: ignore
                    object_=_response_json,
                ),
            )
            return AsyncHttpResponse(response=_response, data=_data)
        if "errorName" in _response_json:
            if _response_json["errorName"] == "VersionConflictError":
                raise VersionConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        VersionConflictErrorBody,
                        parse_obj_as(
                            type_=VersionConflictErrorBody,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    ),
                )
            if _response_json["errorName"] == "NotFoundError":
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorBase4Xx,
                        parse_obj_as(
                            type_=ErrorBase4Xx,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    ),
                )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_visits(
        self,
        *,
        page_token: typing.Optional[PageToken] = None,
        limit: typing.Optional[int] = None,
        sort_field: typing.Optional[SortFieldString] = None,
        sort_direction: typing.Optional[SortDirection] = None,
        filters: typing.Optional[FilterQueryString] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[VisitsPage]:
        """
        Gets all Visits within a given time range. The return list is ordered by start_time ascending.

        **IMPORTANT:** This endpoint requires a date filter on `appointment.startTimestamp` to ensure acceptable query performance.
        Without date filtering, the query can take 50+ seconds on large datasets due to grouping and aggregation operations.

        Example filters:
        - `appointment.startTimestamp|gt|2024-01-01` - appointments after January 1, 2024
        - `appointment.startTimestamp|eq|2024-12-08` - appointments on December 8, 2024
        - `appointment.startTimestamp|lt|2024-12-31` - appointments before December 31, 2024

        You can combine the date filter with other filters using commas:
        - `appointment.startTimestamp|gt|2024-01-01,appointment.status|eq|PENDING`

        Parameters
        ----------
        page_token : typing.Optional[PageToken]

        limit : typing.Optional[int]

        sort_field : typing.Optional[SortFieldString]
            Defaults to appointment.start_time.

        sort_direction : typing.Optional[SortDirection]
            Defaults to ascending.

        filters : typing.Optional[FilterQueryString]
            **Required:** Must include a date filter on appointment.startTimestamp (using gt, lt, or eq operators).
            Example: appointment.startTimestamp|gt|2024-01-01

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

        Returns
        -------
        AsyncHttpResponse[VisitsPage]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "appointments/v1/visits",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="GET",
            params={
                "page_token": page_token,
                "limit": limit,
                "sort_field": sort_field,
                "sort_direction": sort_direction,
                "filters": filters,
            },
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        if 200 <= _response.status_code < 300:
            _data = typing.cast(
                VisitsPage,
                parse_obj_as(
                    type_=VisitsPage,  # type: ignore
                    object_=_response_json,
                ),
            )
            return AsyncHttpResponse(response=_response, data=_data)
        if "errorName" in _response_json:
            if _response_json["errorName"] == "BadRequestError":
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorBase4Xx,
                        parse_obj_as(
                            type_=ErrorBase4Xx,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    ),
                )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get(
        self, id: AppointmentId, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[Appointment]:
        """
        Gets an appointment.

        Parameters
        ----------
        id : AppointmentId

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

        Returns
        -------
        AsyncHttpResponse[Appointment]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"appointments/v1/{jsonable_encoder(id)}",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="GET",
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        if 200 <= _response.status_code < 300:
            _data = typing.cast(
                Appointment,
                parse_obj_as(
                    type_=Appointment,  # type: ignore
                    object_=_response_json,
                ),
            )
            return AsyncHttpResponse(response=_response, data=_data)
        if "errorName" in _response_json:
            if _response_json["errorName"] == "NotFoundError":
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorBase4Xx,
                        parse_obj_as(
                            type_=ErrorBase4Xx,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    ),
                )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_history(
        self, id: AppointmentId, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[typing.List[Appointment]]:
        """
        Gets an appointment along with it's full history.  The return list is ordered by version ascending.

        Parameters
        ----------
        id : AppointmentId

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

        Returns
        -------
        AsyncHttpResponse[typing.List[Appointment]]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"appointments/v1/{jsonable_encoder(id)}/history",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="GET",
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        if 200 <= _response.status_code < 300:
            _data = typing.cast(
                typing.List[Appointment],
                parse_obj_as(
                    type_=typing.List[Appointment],  # type: ignore
                    object_=_response_json,
                ),
            )
            return AsyncHttpResponse(response=_response, data=_data)
        if "errorName" in _response_json:
            if _response_json["errorName"] == "NotFoundError":
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorBase4Xx,
                        parse_obj_as(
                            type_=ErrorBase4Xx,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    ),
                )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def update(
        self,
        id: AppointmentId,
        version: str,
        *,
        request: MutableAppointment,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[Appointment]:
        """
        Updates an appointment. The path must contain the next version number to prevent race conditions. For example, if the current version of the appointment is n, you will need to send a request to this endpoint with `/{id}/n+1` to update the appointment. Updating historic versions is not supported.

        Parameters
        ----------
        id : AppointmentId

        version : str

        request : MutableAppointment

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

        Returns
        -------
        AsyncHttpResponse[Appointment]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"appointments/v1/{jsonable_encoder(id)}/{jsonable_encoder(version)}",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="PUT",
            json=request,
            request_options=request_options,
            omit=OMIT,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        if 200 <= _response.status_code < 300:
            _data = typing.cast(
                Appointment,
                parse_obj_as(
                    type_=Appointment,  # type: ignore
                    object_=_response_json,
                ),
            )
            return AsyncHttpResponse(response=_response, data=_data)
        if "errorName" in _response_json:
            if _response_json["errorName"] == "NotFoundError":
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorBase4Xx,
                        parse_obj_as(
                            type_=ErrorBase4Xx,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    ),
                )
            if _response_json["errorName"] == "VersionConflictError":
                raise VersionConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        VersionConflictErrorBody,
                        parse_obj_as(
                            type_=VersionConflictErrorBody,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    ),
                )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def scan(
        self, *, since: dt.datetime, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[typing.List[Appointment]]:
        """
        Scans up to 100 appointment updates.  The since query parameter is inclusive, and the result list is ordered by updatedAt ascending.

        Parameters
        ----------
        since : dt.datetime

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

        Returns
        -------
        AsyncHttpResponse[typing.List[Appointment]]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "appointments/v1/updates/scan",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="GET",
            params={
                "since": serialize_datetime(since),
            },
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        if 200 <= _response.status_code < 300:
            _data = typing.cast(
                typing.List[Appointment],
                parse_obj_as(
                    type_=typing.List[Appointment],  # type: ignore
                    object_=_response_json,
                ),
            )
            return AsyncHttpResponse(response=_response, data=_data)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def deactivate(
        self, id: AppointmentId, version: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[None]:
        """
        Sets an appointment as deactivated.  The path must contain the most recent version to prevent race conditions.  Deactivating historic versions is not supported. Subsequent updates via PUT to the appointment will "reactivate" the appointment and set the deactivated flag to false.

        Parameters
        ----------
        id : AppointmentId

        version : str

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

        Returns
        -------
        AsyncHttpResponse[None]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"appointments/v1/{jsonable_encoder(id)}/{jsonable_encoder(version)}",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="DELETE",
            request_options=request_options,
        )
        if 200 <= _response.status_code < 300:
            return AsyncHttpResponse(response=_response, data=None)
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        if "errorName" in _response_json:
            if _response_json["errorName"] == "NotFoundError":
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorBase4Xx,
                        parse_obj_as(
                            type_=ErrorBase4Xx,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    ),
                )
            if _response_json["errorName"] == "VersionConflictError":
                raise VersionConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        VersionConflictErrorBody,
                        parse_obj_as(
                            type_=VersionConflictErrorBody,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    ),
                )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
