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

import datetime as dt
import typing

from .......core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from .......core.request_options import RequestOptions
from ....common.types.appointment_id import AppointmentId
from ....common.types.page_token import PageToken
from ....common.types.sort_direction import SortDirection
from ....lists.resources.v_1.types.filter_query_string import FilterQueryString
from ....lists.resources.v_1.types.sort_field_string import SortFieldString
from .raw_client import AsyncRawV1Client, RawV1Client
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 V1Client:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawV1Client(client_wrapper=client_wrapper)

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

        Returns
        -------
        RawV1Client
        """
        return self._raw_client

    def create(
        self, *, request: MutableAppointment, request_options: typing.Optional[RequestOptions] = None
    ) -> 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
        -------
        Appointment

        Examples
        --------
        import datetime

        from candid import CandidApiClient
        from candid.resources.pre_encounter.resources.appointments.resources.v_1 import (
            MutableAppointment,
            Service,
        )

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.pre_encounter.appointments.v_1.create(
            request=MutableAppointment(
                patient_id="patient_id",
                start_timestamp=datetime.datetime.fromisoformat(
                    "2024-01-15 09:30:00+00:00",
                ),
                service_duration=1,
                services=[Service(), Service()],
            ),
        )
        """
        _response = self._raw_client.create(request=request, request_options=request_options)
        return _response.data

    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,
    ) -> VisitsPage:
        """
        Gets all Visits within a given time range. The return list is ordered by start_time ascending.

        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]

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

        Returns
        -------
        VisitsPage

        Examples
        --------
        from candid import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.pre_encounter.appointments.v_1.get_visits()
        """
        _response = self._raw_client.get_visits(
            page_token=page_token,
            limit=limit,
            sort_field=sort_field,
            sort_direction=sort_direction,
            filters=filters,
            request_options=request_options,
        )
        return _response.data

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

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

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

        Returns
        -------
        Appointment

        Examples
        --------
        from candid import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.pre_encounter.appointments.v_1.get(
            id="id",
        )
        """
        _response = self._raw_client.get(id, request_options=request_options)
        return _response.data

    def get_history(
        self, id: AppointmentId, *, request_options: typing.Optional[RequestOptions] = None
    ) -> 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
        -------
        typing.List[Appointment]

        Examples
        --------
        from candid import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.pre_encounter.appointments.v_1.get_history(
            id="id",
        )
        """
        _response = self._raw_client.get_history(id, request_options=request_options)
        return _response.data

    def update(
        self,
        id: AppointmentId,
        version: str,
        *,
        request: MutableAppointment,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Appointment:
        """
        Updates an appointment.  The path must contain the most recent version to prevent race conditions.  Updating historic versions is not supported.

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

        version : str

        request : MutableAppointment

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

        Returns
        -------
        Appointment

        Examples
        --------
        import datetime

        from candid import CandidApiClient
        from candid.resources.pre_encounter.resources.appointments.resources.v_1 import (
            MutableAppointment,
            Service,
        )

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.pre_encounter.appointments.v_1.update(
            id="id",
            version="version",
            request=MutableAppointment(
                patient_id="patient_id",
                start_timestamp=datetime.datetime.fromisoformat(
                    "2024-01-15 09:30:00+00:00",
                ),
                service_duration=1,
                services=[Service(), Service()],
            ),
        )
        """
        _response = self._raw_client.update(id, version, request=request, request_options=request_options)
        return _response.data

    def scan(
        self, *, since: dt.datetime, request_options: typing.Optional[RequestOptions] = None
    ) -> 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
        -------
        typing.List[Appointment]

        Examples
        --------
        import datetime

        from candid import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.pre_encounter.appointments.v_1.scan(
            since=datetime.datetime.fromisoformat(
                "2024-01-15 09:30:00+00:00",
            ),
        )
        """
        _response = self._raw_client.scan(since=since, request_options=request_options)
        return _response.data

    def deactivate(
        self, id: AppointmentId, version: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> 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
        -------
        None

        Examples
        --------
        from candid import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.pre_encounter.appointments.v_1.deactivate(
            id="id",
            version="version",
        )
        """
        _response = self._raw_client.deactivate(id, version, request_options=request_options)
        return _response.data


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

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

        Returns
        -------
        AsyncRawV1Client
        """
        return self._raw_client

    async def create(
        self, *, request: MutableAppointment, request_options: typing.Optional[RequestOptions] = None
    ) -> 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
        -------
        Appointment

        Examples
        --------
        import asyncio
        import datetime

        from candid import AsyncCandidApiClient
        from candid.resources.pre_encounter.resources.appointments.resources.v_1 import (
            MutableAppointment,
            Service,
        )

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.pre_encounter.appointments.v_1.create(
                request=MutableAppointment(
                    patient_id="patient_id",
                    start_timestamp=datetime.datetime.fromisoformat(
                        "2024-01-15 09:30:00+00:00",
                    ),
                    service_duration=1,
                    services=[Service(), Service()],
                ),
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.create(request=request, request_options=request_options)
        return _response.data

    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,
    ) -> VisitsPage:
        """
        Gets all Visits within a given time range. The return list is ordered by start_time ascending.

        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]

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

        Returns
        -------
        VisitsPage

        Examples
        --------
        import asyncio

        from candid import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.pre_encounter.appointments.v_1.get_visits()


        asyncio.run(main())
        """
        _response = await self._raw_client.get_visits(
            page_token=page_token,
            limit=limit,
            sort_field=sort_field,
            sort_direction=sort_direction,
            filters=filters,
            request_options=request_options,
        )
        return _response.data

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

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

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

        Returns
        -------
        Appointment

        Examples
        --------
        import asyncio

        from candid import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.pre_encounter.appointments.v_1.get(
                id="id",
            )


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

    async def get_history(
        self, id: AppointmentId, *, request_options: typing.Optional[RequestOptions] = None
    ) -> 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
        -------
        typing.List[Appointment]

        Examples
        --------
        import asyncio

        from candid import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.pre_encounter.appointments.v_1.get_history(
                id="id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get_history(id, request_options=request_options)
        return _response.data

    async def update(
        self,
        id: AppointmentId,
        version: str,
        *,
        request: MutableAppointment,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Appointment:
        """
        Updates an appointment.  The path must contain the most recent version to prevent race conditions.  Updating historic versions is not supported.

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

        version : str

        request : MutableAppointment

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

        Returns
        -------
        Appointment

        Examples
        --------
        import asyncio
        import datetime

        from candid import AsyncCandidApiClient
        from candid.resources.pre_encounter.resources.appointments.resources.v_1 import (
            MutableAppointment,
            Service,
        )

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.pre_encounter.appointments.v_1.update(
                id="id",
                version="version",
                request=MutableAppointment(
                    patient_id="patient_id",
                    start_timestamp=datetime.datetime.fromisoformat(
                        "2024-01-15 09:30:00+00:00",
                    ),
                    service_duration=1,
                    services=[Service(), Service()],
                ),
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.update(id, version, request=request, request_options=request_options)
        return _response.data

    async def scan(
        self, *, since: dt.datetime, request_options: typing.Optional[RequestOptions] = None
    ) -> 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
        -------
        typing.List[Appointment]

        Examples
        --------
        import asyncio
        import datetime

        from candid import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.pre_encounter.appointments.v_1.scan(
                since=datetime.datetime.fromisoformat(
                    "2024-01-15 09:30:00+00:00",
                ),
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.scan(since=since, request_options=request_options)
        return _response.data

    async def deactivate(
        self, id: AppointmentId, version: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> 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
        -------
        None

        Examples
        --------
        import asyncio

        from candid import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.pre_encounter.appointments.v_1.deactivate(
                id="id",
                version="version",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.deactivate(id, version, request_options=request_options)
        return _response.data
