# 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 ..errors.unprocessable_entity_error import UnprocessableEntityError
from ..types.calendar_connection_list_response import CalendarConnectionListResponse
from ..types.calendar_event_list_response import CalendarEventListResponse
from ..types.calendar_event_response import CalendarEventResponse
from ..types.calendar_sync_response import CalendarSyncResponse
from ..types.org_calendar_connection_list_response import OrgCalendarConnectionListResponse
from ..types.org_calendar_connection_response import OrgCalendarConnectionResponse
from .types.connect_calendar_response import ConnectCalendarResponse

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


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

    def list_calendar_events(
        self,
        *,
        skip: typing.Optional[int] = None,
        limit: typing.Optional[int] = None,
        start_after: typing.Optional[dt.datetime] = None,
        start_before: typing.Optional[dt.datetime] = None,
        start_date: typing.Optional[dt.datetime] = None,
        end_date: typing.Optional[dt.datetime] = None,
        provider: typing.Optional[str] = None,
        auto_join_status: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[CalendarEventListResponse]:
        """
        List calendar events for the authenticated user.

        Parameters
        ----------
        skip : typing.Optional[int]
            Number of items to skip

        limit : typing.Optional[int]
            Max items to return

        start_after : typing.Optional[dt.datetime]
            Filter: events starting after

        start_before : typing.Optional[dt.datetime]
            Filter: events starting before

        start_date : typing.Optional[dt.datetime]
            Alias for start_after (UI compat)

        end_date : typing.Optional[dt.datetime]
            Alias for start_before (UI compat)

        provider : typing.Optional[str]
            Filter by calendar provider

        auto_join_status : typing.Optional[str]
            Filter by auto-join status

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

        Returns
        -------
        HttpResponse[CalendarEventListResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/meeting-buddy/calendar/events",
            method="GET",
            params={
                "skip": skip,
                "limit": limit,
                "start_after": serialize_datetime(start_after) if start_after is not None else None,
                "start_before": serialize_datetime(start_before) if start_before is not None else None,
                "start_date": serialize_datetime(start_date) if start_date is not None else None,
                "end_date": serialize_datetime(end_date) if end_date is not None else None,
                "provider": provider,
                "auto_join_status": auto_join_status,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CalendarEventListResponse,
                    parse_obj_as(
                        type_=CalendarEventListResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_calendar_event(
        self, event_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[CalendarEventResponse]:
        """
        Get details for a specific calendar event.

        Parameters
        ----------
        event_id : str

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

        Returns
        -------
        HttpResponse[CalendarEventResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/meeting-buddy/calendar/events/{jsonable_encoder(event_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CalendarEventResponse,
                    parse_obj_as(
                        type_=CalendarEventResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def update_calendar_event(
        self, event_id: str, *, auto_join_status: str, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[CalendarEventResponse]:
        """
        Override auto-join status for a specific event.

        Parameters
        ----------
        event_id : str

        auto_join_status : str
            Set to 'disabled' to prevent auto-join, or 'pending' to re-enable evaluation.

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

        Returns
        -------
        HttpResponse[CalendarEventResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/meeting-buddy/calendar/events/{jsonable_encoder(event_id)}",
            method="PATCH",
            json={
                "auto_join_status": auto_join_status,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CalendarEventResponse,
                    parse_obj_as(
                        type_=CalendarEventResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def trigger_calendar_sync(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[CalendarSyncResponse]:
        """
        Trigger a manual sync of all connected calendars.

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

        Returns
        -------
        HttpResponse[CalendarSyncResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/meeting-buddy/calendar/sync",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CalendarSyncResponse,
                    parse_obj_as(
                        type_=CalendarSyncResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def list_calendar_connections(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[CalendarConnectionListResponse]:
        """
        List all connected calendar providers for the authenticated user.

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

        Returns
        -------
        HttpResponse[CalendarConnectionListResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/meeting-buddy/calendar/connections",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CalendarConnectionListResponse,
                    parse_obj_as(
                        type_=CalendarConnectionListResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def connect_calendar(
        self,
        *,
        provider: str,
        credentials: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ConnectCalendarResponse]:
        """
        Connect a calendar provider via OAuth or credentials.

        Parameters
        ----------
        provider : str
            Calendar provider: google_calendar, outlook_calendar, zoom, apple_calendar

        credentials : typing.Optional[typing.Dict[str, typing.Any]]
            Credentials for Apple Calendar (required when provider=apple_calendar). Two connection methods are supported: 1) App-specific password — provide {"apple_id": "user@icloud.com", "app_specific_password": "xxxx-xxxx-xxxx-xxxx"}. Requires an app-specific password generated at appleid.apple.com. 2) iCal URL — provide {"ical_url": "webcal://p123-calendars.icloud.com/..."}. Read-only; fetches events via public/private calendar feed URL. Not required for OAuth providers (google_calendar, outlook_calendar, zoom).

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

        Returns
        -------
        HttpResponse[ConnectCalendarResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/meeting-buddy/calendar/connections",
            method="POST",
            json={
                "provider": provider,
                "credentials": credentials,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ConnectCalendarResponse,
                    parse_obj_as(
                        type_=ConnectCalendarResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def disconnect_calendar(
        self, credential_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[None]:
        """
        Disconnect a calendar and remove associated events.

        Parameters
        ----------
        credential_id : str

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

        Returns
        -------
        HttpResponse[None]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/meeting-buddy/calendar/connections/{jsonable_encoder(credential_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return HttpResponse(response=_response, data=None)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def list_org_calendar_connections(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[OrgCalendarConnectionListResponse]:
        """
        List organization-level calendar connections (admin-only).

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

        Returns
        -------
        HttpResponse[OrgCalendarConnectionListResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/meeting-buddy/calendar/org-connections",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    OrgCalendarConnectionListResponse,
                    parse_obj_as(
                        type_=OrgCalendarConnectionListResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def connect_org_calendar(
        self,
        *,
        provider: str,
        credential_id: str,
        calendar_name: str,
        account_email: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[OrgCalendarConnectionResponse]:
        """
        Connect an organization-level shared calendar (admin-only).

        Parameters
        ----------
        provider : str
            Calendar provider: google_calendar, outlook_calendar, zoom

        credential_id : str
            ID of the admin's OAuth credential to use for syncing

        calendar_name : str
            Display name for this shared calendar

        account_email : str
            Service account or admin email

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

        Returns
        -------
        HttpResponse[OrgCalendarConnectionResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/meeting-buddy/calendar/org-connections",
            method="POST",
            json={
                "provider": provider,
                "credential_id": credential_id,
                "calendar_name": calendar_name,
                "account_email": account_email,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    OrgCalendarConnectionResponse,
                    parse_obj_as(
                        type_=OrgCalendarConnectionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def disconnect_org_calendar(
        self, connection_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[None]:
        """
        Disconnect an organization-level calendar (admin-only).

        Parameters
        ----------
        connection_id : str

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

        Returns
        -------
        HttpResponse[None]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/meeting-buddy/calendar/org-connections/{jsonable_encoder(connection_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return HttpResponse(response=_response, data=None)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def sync_org_calendar(
        self, connection_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[CalendarSyncResponse]:
        """
        Trigger manual sync for an org-level calendar (admin-only).

        Parameters
        ----------
        connection_id : str

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

        Returns
        -------
        HttpResponse[CalendarSyncResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/meeting-buddy/calendar/org-connections/{jsonable_encoder(connection_id)}/sync",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CalendarSyncResponse,
                    parse_obj_as(
                        type_=CalendarSyncResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def receive_calendar_webhook(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[typing.Dict[str, typing.Any]]:
        """
        Receive push notifications from calendar providers.

        This is a system endpoint with no authentication — providers call this
        directly. Signature validation is done inside the handler.

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

        Returns
        -------
        HttpResponse[typing.Dict[str, typing.Any]]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/meeting-buddy/calendar/webhooks",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Dict[str, typing.Any],
                    parse_obj_as(
                        type_=typing.Dict[str, typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


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

    async def list_calendar_events(
        self,
        *,
        skip: typing.Optional[int] = None,
        limit: typing.Optional[int] = None,
        start_after: typing.Optional[dt.datetime] = None,
        start_before: typing.Optional[dt.datetime] = None,
        start_date: typing.Optional[dt.datetime] = None,
        end_date: typing.Optional[dt.datetime] = None,
        provider: typing.Optional[str] = None,
        auto_join_status: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[CalendarEventListResponse]:
        """
        List calendar events for the authenticated user.

        Parameters
        ----------
        skip : typing.Optional[int]
            Number of items to skip

        limit : typing.Optional[int]
            Max items to return

        start_after : typing.Optional[dt.datetime]
            Filter: events starting after

        start_before : typing.Optional[dt.datetime]
            Filter: events starting before

        start_date : typing.Optional[dt.datetime]
            Alias for start_after (UI compat)

        end_date : typing.Optional[dt.datetime]
            Alias for start_before (UI compat)

        provider : typing.Optional[str]
            Filter by calendar provider

        auto_join_status : typing.Optional[str]
            Filter by auto-join status

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

        Returns
        -------
        AsyncHttpResponse[CalendarEventListResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/meeting-buddy/calendar/events",
            method="GET",
            params={
                "skip": skip,
                "limit": limit,
                "start_after": serialize_datetime(start_after) if start_after is not None else None,
                "start_before": serialize_datetime(start_before) if start_before is not None else None,
                "start_date": serialize_datetime(start_date) if start_date is not None else None,
                "end_date": serialize_datetime(end_date) if end_date is not None else None,
                "provider": provider,
                "auto_join_status": auto_join_status,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CalendarEventListResponse,
                    parse_obj_as(
                        type_=CalendarEventListResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_calendar_event(
        self, event_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[CalendarEventResponse]:
        """
        Get details for a specific calendar event.

        Parameters
        ----------
        event_id : str

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

        Returns
        -------
        AsyncHttpResponse[CalendarEventResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/meeting-buddy/calendar/events/{jsonable_encoder(event_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CalendarEventResponse,
                    parse_obj_as(
                        type_=CalendarEventResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def update_calendar_event(
        self, event_id: str, *, auto_join_status: str, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[CalendarEventResponse]:
        """
        Override auto-join status for a specific event.

        Parameters
        ----------
        event_id : str

        auto_join_status : str
            Set to 'disabled' to prevent auto-join, or 'pending' to re-enable evaluation.

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

        Returns
        -------
        AsyncHttpResponse[CalendarEventResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/meeting-buddy/calendar/events/{jsonable_encoder(event_id)}",
            method="PATCH",
            json={
                "auto_join_status": auto_join_status,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CalendarEventResponse,
                    parse_obj_as(
                        type_=CalendarEventResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def trigger_calendar_sync(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[CalendarSyncResponse]:
        """
        Trigger a manual sync of all connected calendars.

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

        Returns
        -------
        AsyncHttpResponse[CalendarSyncResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/meeting-buddy/calendar/sync",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CalendarSyncResponse,
                    parse_obj_as(
                        type_=CalendarSyncResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def list_calendar_connections(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[CalendarConnectionListResponse]:
        """
        List all connected calendar providers for the authenticated user.

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

        Returns
        -------
        AsyncHttpResponse[CalendarConnectionListResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/meeting-buddy/calendar/connections",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CalendarConnectionListResponse,
                    parse_obj_as(
                        type_=CalendarConnectionListResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def connect_calendar(
        self,
        *,
        provider: str,
        credentials: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ConnectCalendarResponse]:
        """
        Connect a calendar provider via OAuth or credentials.

        Parameters
        ----------
        provider : str
            Calendar provider: google_calendar, outlook_calendar, zoom, apple_calendar

        credentials : typing.Optional[typing.Dict[str, typing.Any]]
            Credentials for Apple Calendar (required when provider=apple_calendar). Two connection methods are supported: 1) App-specific password — provide {"apple_id": "user@icloud.com", "app_specific_password": "xxxx-xxxx-xxxx-xxxx"}. Requires an app-specific password generated at appleid.apple.com. 2) iCal URL — provide {"ical_url": "webcal://p123-calendars.icloud.com/..."}. Read-only; fetches events via public/private calendar feed URL. Not required for OAuth providers (google_calendar, outlook_calendar, zoom).

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

        Returns
        -------
        AsyncHttpResponse[ConnectCalendarResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/meeting-buddy/calendar/connections",
            method="POST",
            json={
                "provider": provider,
                "credentials": credentials,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ConnectCalendarResponse,
                    parse_obj_as(
                        type_=ConnectCalendarResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def disconnect_calendar(
        self, credential_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[None]:
        """
        Disconnect a calendar and remove associated events.

        Parameters
        ----------
        credential_id : str

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

        Returns
        -------
        AsyncHttpResponse[None]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/meeting-buddy/calendar/connections/{jsonable_encoder(credential_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return AsyncHttpResponse(response=_response, data=None)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def list_org_calendar_connections(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[OrgCalendarConnectionListResponse]:
        """
        List organization-level calendar connections (admin-only).

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

        Returns
        -------
        AsyncHttpResponse[OrgCalendarConnectionListResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/meeting-buddy/calendar/org-connections",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    OrgCalendarConnectionListResponse,
                    parse_obj_as(
                        type_=OrgCalendarConnectionListResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def connect_org_calendar(
        self,
        *,
        provider: str,
        credential_id: str,
        calendar_name: str,
        account_email: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[OrgCalendarConnectionResponse]:
        """
        Connect an organization-level shared calendar (admin-only).

        Parameters
        ----------
        provider : str
            Calendar provider: google_calendar, outlook_calendar, zoom

        credential_id : str
            ID of the admin's OAuth credential to use for syncing

        calendar_name : str
            Display name for this shared calendar

        account_email : str
            Service account or admin email

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

        Returns
        -------
        AsyncHttpResponse[OrgCalendarConnectionResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/meeting-buddy/calendar/org-connections",
            method="POST",
            json={
                "provider": provider,
                "credential_id": credential_id,
                "calendar_name": calendar_name,
                "account_email": account_email,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    OrgCalendarConnectionResponse,
                    parse_obj_as(
                        type_=OrgCalendarConnectionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def disconnect_org_calendar(
        self, connection_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[None]:
        """
        Disconnect an organization-level calendar (admin-only).

        Parameters
        ----------
        connection_id : str

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

        Returns
        -------
        AsyncHttpResponse[None]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/meeting-buddy/calendar/org-connections/{jsonable_encoder(connection_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return AsyncHttpResponse(response=_response, data=None)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def sync_org_calendar(
        self, connection_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[CalendarSyncResponse]:
        """
        Trigger manual sync for an org-level calendar (admin-only).

        Parameters
        ----------
        connection_id : str

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

        Returns
        -------
        AsyncHttpResponse[CalendarSyncResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/meeting-buddy/calendar/org-connections/{jsonable_encoder(connection_id)}/sync",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CalendarSyncResponse,
                    parse_obj_as(
                        type_=CalendarSyncResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def receive_calendar_webhook(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[typing.Dict[str, typing.Any]]:
        """
        Receive push notifications from calendar providers.

        This is a system endpoint with no authentication — providers call this
        directly. Signature validation is done inside the handler.

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

        Returns
        -------
        AsyncHttpResponse[typing.Dict[str, typing.Any]]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/meeting-buddy/calendar/webhooks",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Dict[str, typing.Any],
                    parse_obj_as(
                        type_=typing.Dict[str, typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
