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

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

import httpx
import pydantic

from .....core.api_error import ApiError
from .....core.datetime_utils import serialize_datetime
from .....core.jsonable_encoder import jsonable_encoder
from .....core.remove_none_from_headers import remove_none_from_headers
from .....environment import CandidApiEnvironment
from ....billing_notes.types.billing_note_base import BillingNoteBase
from ....claims.types.claim_status import ClaimStatus
from ....commons.types.date import Date
from ....commons.types.encounter_external_id import EncounterExternalId
from ....commons.types.encounter_id import EncounterId
from ....commons.types.facility_type_code import FacilityTypeCode
from ....commons.types.page_token import PageToken
from ....commons.types.street_address_long_zip import StreetAddressLongZip
from ....commons.types.work_queue_id import WorkQueueId
from ....diagnoses.types.diagnosis_create import DiagnosisCreate
from ....diagnoses.types.diagnosis_id import DiagnosisId
from ....encounter_providers.resources.v_2.types.billing_provider import BillingProvider
from ....encounter_providers.resources.v_2.types.referring_provider import ReferringProvider
from ....encounter_providers.resources.v_2.types.rendering_provider import RenderingProvider
from ....individual.types.patient_create import PatientCreate
from ....individual.types.subscriber_create import SubscriberCreate
from ....service_facility.types.encounter_service_facility_base import EncounterServiceFacilityBase
from ....service_lines.types.service_line_create import ServiceLineCreate
from ....tags.types.tag_id import TagId
from .types.clinical_note_category_create import ClinicalNoteCategoryCreate
from .types.encounter import Encounter
from .types.encounter_attachment import EncounterAttachment
from .types.encounter_page import EncounterPage
from .types.encounter_sort_options import EncounterSortOptions
from .types.generate_clinical_notes_pdf_response import GenerateClinicalNotesPdfResponse
from .types.intervention import Intervention
from .types.mark_as_not_billable_response import MarkAsNotBillableResponse
from .types.medication import Medication
from .types.network_status_computation_results import NetworkStatusComputationResults
from .types.patient_history_category import PatientHistoryCategory
from .types.prior_authorization_number import PriorAuthorizationNumber
from .types.synchronicity_type import SynchronicityType
from .types.vitals import Vitals

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


class V4Client:
    def __init__(
        self, *, environment: CandidApiEnvironment = CandidApiEnvironment.PRODUCTION, token: typing.Optional[str] = None
    ):
        self._environment = environment
        self._token = token

    def get_all(
        self,
        *,
        limit: typing.Optional[int] = None,
        claim_status: typing.Optional[ClaimStatus] = None,
        sort: typing.Optional[EncounterSortOptions] = None,
        page_token: typing.Optional[PageToken] = None,
        date_of_service_min: typing.Optional[Date] = None,
        date_of_service_max: typing.Optional[Date] = None,
        primary_payer_names: typing.Optional[str] = None,
        search_term: typing.Optional[str] = None,
        external_id: typing.Optional[EncounterExternalId] = None,
        diagnoses_updated_since: typing.Optional[dt.datetime] = None,
        tag_ids: typing.Union[typing.Optional[TagId], typing.List[TagId]],
        do_not_bill: typing.Optional[bool] = None,
        work_queue_id: typing.Optional[WorkQueueId] = None,
    ) -> EncounterPage:
        _response = httpx.request(
            "GET",
            urllib.parse.urljoin(f"{self._environment.value}/", "api/encounters/v4"),
            params={
                "limit": limit,
                "claim_status": claim_status,
                "sort": sort,
                "page_token": page_token,
                "date_of_service_min": date_of_service_min,
                "date_of_service_max": date_of_service_max,
                "primary_payer_names": primary_payer_names,
                "search_term": search_term,
                "external_id": external_id,
                "diagnoses_updated_since": serialize_datetime(diagnoses_updated_since)
                if diagnoses_updated_since is not None
                else None,
                "tag_ids": tag_ids,
                "do_not_bill": do_not_bill,
                "work_queue_id": work_queue_id,
            },
            headers=remove_none_from_headers(
                {"Authorization": f"Bearer {self._token}" if self._token is not None else None}
            ),
            timeout=60,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(EncounterPage, _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get(self, encounter_id: EncounterId) -> Encounter:
        _response = httpx.request(
            "GET",
            urllib.parse.urljoin(f"{self._environment.value}/", f"api/encounters/v4/{encounter_id}"),
            headers=remove_none_from_headers(
                {"Authorization": f"Bearer {self._token}" if self._token is not None else None}
            ),
            timeout=60,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(Encounter, _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def create(
        self,
        *,
        patient: PatientCreate,
        billing_provider: BillingProvider,
        rendering_provider: RenderingProvider,
        referring_provider: typing.Optional[ReferringProvider] = OMIT,
        service_facility: typing.Optional[EncounterServiceFacilityBase] = OMIT,
        subscriber_primary: typing.Optional[SubscriberCreate] = OMIT,
        subscriber_secondary: typing.Optional[SubscriberCreate] = OMIT,
        diagnoses: typing.List[DiagnosisCreate],
        clinical_notes: typing.Optional[typing.List[ClinicalNoteCategoryCreate]] = OMIT,
        billing_notes: typing.Optional[typing.List[BillingNoteBase]] = OMIT,
        place_of_service_code: FacilityTypeCode,
        patient_histories: typing.Optional[typing.List[PatientHistoryCategory]] = OMIT,
        service_lines: typing.Optional[typing.List[ServiceLineCreate]] = OMIT,
        external_id: typing.Optional[EncounterExternalId] = OMIT,
        date_of_service: Date,
        end_date_of_service: typing.Optional[Date] = OMIT,
        prior_authorization_number: typing.Optional[PriorAuthorizationNumber] = OMIT,
        patient_authorized_release: bool,
        benefits_assigned_to_provider: bool,
        provider_accepts_assignment: bool,
        appointment_type: typing.Optional[str] = OMIT,
        do_not_bill: typing.Optional[bool] = OMIT,
        existing_medications: typing.Optional[typing.List[Medication]] = OMIT,
        vitals: typing.Optional[Vitals] = OMIT,
        interventions: typing.Optional[typing.List[Intervention]] = OMIT,
        pay_to_address: typing.Optional[StreetAddressLongZip] = OMIT,
        synchronicity: typing.Optional[SynchronicityType] = OMIT,
    ) -> Encounter:
        _request: typing.Dict[str, typing.Any] = {
            "patient": patient,
            "billing_provider": billing_provider,
            "rendering_provider": rendering_provider,
            "diagnoses": diagnoses,
            "place_of_service_code": place_of_service_code,
            "date_of_service": date_of_service,
            "patient_authorized_release": patient_authorized_release,
            "benefits_assigned_to_provider": benefits_assigned_to_provider,
            "provider_accepts_assignment": provider_accepts_assignment,
        }
        if referring_provider is not OMIT:
            _request["referring_provider"] = referring_provider
        if service_facility is not OMIT:
            _request["service_facility"] = service_facility
        if subscriber_primary is not OMIT:
            _request["subscriber_primary"] = subscriber_primary
        if subscriber_secondary is not OMIT:
            _request["subscriber_secondary"] = subscriber_secondary
        if clinical_notes is not OMIT:
            _request["clinical_notes"] = clinical_notes
        if billing_notes is not OMIT:
            _request["billing_notes"] = billing_notes
        if patient_histories is not OMIT:
            _request["patient_histories"] = patient_histories
        if service_lines is not OMIT:
            _request["service_lines"] = service_lines
        if external_id is not OMIT:
            _request["external_id"] = external_id
        if end_date_of_service is not OMIT:
            _request["end_date_of_service"] = end_date_of_service
        if prior_authorization_number is not OMIT:
            _request["prior_authorization_number"] = prior_authorization_number
        if appointment_type is not OMIT:
            _request["appointment_type"] = appointment_type
        if do_not_bill is not OMIT:
            _request["do_not_bill"] = do_not_bill
        if existing_medications is not OMIT:
            _request["existing_medications"] = existing_medications
        if vitals is not OMIT:
            _request["vitals"] = vitals
        if interventions is not OMIT:
            _request["interventions"] = interventions
        if pay_to_address is not OMIT:
            _request["pay_to_address"] = pay_to_address
        if synchronicity is not OMIT:
            _request["synchronicity"] = synchronicity
        _response = httpx.request(
            "POST",
            urllib.parse.urljoin(f"{self._environment.value}/", "api/encounters/v4"),
            json=jsonable_encoder(_request),
            headers=remove_none_from_headers(
                {"Authorization": f"Bearer {self._token}" if self._token is not None else None}
            ),
            timeout=60,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(Encounter, _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def update(
        self,
        encounter_id: EncounterId,
        *,
        prior_authorization_number: typing.Optional[PriorAuthorizationNumber] = OMIT,
        external_id: typing.Optional[EncounterExternalId] = OMIT,
        date_of_service: typing.Optional[Date] = OMIT,
        diagnosis_ids: typing.Optional[typing.List[DiagnosisId]] = OMIT,
        tag_ids: typing.Optional[typing.List[TagId]] = OMIT,
        clinical_notes: typing.Optional[typing.List[ClinicalNoteCategoryCreate]] = OMIT,
        pay_to_address: typing.Optional[StreetAddressLongZip] = OMIT,
    ) -> Encounter:
        _request: typing.Dict[str, typing.Any] = {}
        if prior_authorization_number is not OMIT:
            _request["prior_authorization_number"] = prior_authorization_number
        if external_id is not OMIT:
            _request["external_id"] = external_id
        if date_of_service is not OMIT:
            _request["date_of_service"] = date_of_service
        if diagnosis_ids is not OMIT:
            _request["diagnosis_ids"] = diagnosis_ids
        if tag_ids is not OMIT:
            _request["tag_ids"] = tag_ids
        if clinical_notes is not OMIT:
            _request["clinical_notes"] = clinical_notes
        if pay_to_address is not OMIT:
            _request["pay_to_address"] = pay_to_address
        _response = httpx.request(
            "PATCH",
            urllib.parse.urljoin(f"{self._environment.value}/", f"api/encounters/v4/{encounter_id}"),
            json=jsonable_encoder(_request),
            headers=remove_none_from_headers(
                {"Authorization": f"Bearer {self._token}" if self._token is not None else None}
            ),
            timeout=60,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(Encounter, _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_attachments(self, encounter_id: EncounterId) -> typing.List[EncounterAttachment]:
        _response = httpx.request(
            "GET",
            urllib.parse.urljoin(f"{self._environment.value}/", f"api/encounters/v4/{encounter_id}/attachments"),
            headers=remove_none_from_headers(
                {"Authorization": f"Bearer {self._token}" if self._token is not None else None}
            ),
            timeout=60,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.List[EncounterAttachment], _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def generate_clinical_notes_pdf(self, encounter_id: EncounterId) -> GenerateClinicalNotesPdfResponse:
        _response = httpx.request(
            "POST",
            urllib.parse.urljoin(
                f"{self._environment.value}/", f"api/encounters/v4/{encounter_id}/clinical-notes-pdf/generate"
            ),
            headers=remove_none_from_headers(
                {"Authorization": f"Bearer {self._token}" if self._token is not None else None}
            ),
            timeout=60,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(GenerateClinicalNotesPdfResponse, _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def recompute_network_status_results(self, encounter_id: EncounterId) -> NetworkStatusComputationResults:
        _response = httpx.request(
            "PUT",
            urllib.parse.urljoin(
                f"{self._environment.value}/", f"api/encounters/v4/{encounter_id}/network-status-results"
            ),
            headers=remove_none_from_headers(
                {"Authorization": f"Bearer {self._token}" if self._token is not None else None}
            ),
            timeout=60,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(NetworkStatusComputationResults, _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def mark_as_not_billable(self, encounter_id: EncounterId) -> MarkAsNotBillableResponse:
        _response = httpx.request(
            "PUT",
            urllib.parse.urljoin(
                f"{self._environment.value}/", f"api/encounters/v4/{encounter_id}/mark-as-not-billable"
            ),
            headers=remove_none_from_headers(
                {"Authorization": f"Bearer {self._token}" if self._token is not None else None}
            ),
            timeout=60,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(MarkAsNotBillableResponse, _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)


class AsyncV4Client:
    def __init__(
        self, *, environment: CandidApiEnvironment = CandidApiEnvironment.PRODUCTION, token: typing.Optional[str] = None
    ):
        self._environment = environment
        self._token = token

    async def get_all(
        self,
        *,
        limit: typing.Optional[int] = None,
        claim_status: typing.Optional[ClaimStatus] = None,
        sort: typing.Optional[EncounterSortOptions] = None,
        page_token: typing.Optional[PageToken] = None,
        date_of_service_min: typing.Optional[Date] = None,
        date_of_service_max: typing.Optional[Date] = None,
        primary_payer_names: typing.Optional[str] = None,
        search_term: typing.Optional[str] = None,
        external_id: typing.Optional[EncounterExternalId] = None,
        diagnoses_updated_since: typing.Optional[dt.datetime] = None,
        tag_ids: typing.Union[typing.Optional[TagId], typing.List[TagId]],
        do_not_bill: typing.Optional[bool] = None,
        work_queue_id: typing.Optional[WorkQueueId] = None,
    ) -> EncounterPage:
        async with httpx.AsyncClient() as _client:
            _response = await _client.request(
                "GET",
                urllib.parse.urljoin(f"{self._environment.value}/", "api/encounters/v4"),
                params={
                    "limit": limit,
                    "claim_status": claim_status,
                    "sort": sort,
                    "page_token": page_token,
                    "date_of_service_min": date_of_service_min,
                    "date_of_service_max": date_of_service_max,
                    "primary_payer_names": primary_payer_names,
                    "search_term": search_term,
                    "external_id": external_id,
                    "diagnoses_updated_since": serialize_datetime(diagnoses_updated_since)
                    if diagnoses_updated_since is not None
                    else None,
                    "tag_ids": tag_ids,
                    "do_not_bill": do_not_bill,
                    "work_queue_id": work_queue_id,
                },
                headers=remove_none_from_headers(
                    {"Authorization": f"Bearer {self._token}" if self._token is not None else None}
                ),
                timeout=60,
            )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(EncounterPage, _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get(self, encounter_id: EncounterId) -> Encounter:
        async with httpx.AsyncClient() as _client:
            _response = await _client.request(
                "GET",
                urllib.parse.urljoin(f"{self._environment.value}/", f"api/encounters/v4/{encounter_id}"),
                headers=remove_none_from_headers(
                    {"Authorization": f"Bearer {self._token}" if self._token is not None else None}
                ),
                timeout=60,
            )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(Encounter, _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def create(
        self,
        *,
        patient: PatientCreate,
        billing_provider: BillingProvider,
        rendering_provider: RenderingProvider,
        referring_provider: typing.Optional[ReferringProvider] = OMIT,
        service_facility: typing.Optional[EncounterServiceFacilityBase] = OMIT,
        subscriber_primary: typing.Optional[SubscriberCreate] = OMIT,
        subscriber_secondary: typing.Optional[SubscriberCreate] = OMIT,
        diagnoses: typing.List[DiagnosisCreate],
        clinical_notes: typing.Optional[typing.List[ClinicalNoteCategoryCreate]] = OMIT,
        billing_notes: typing.Optional[typing.List[BillingNoteBase]] = OMIT,
        place_of_service_code: FacilityTypeCode,
        patient_histories: typing.Optional[typing.List[PatientHistoryCategory]] = OMIT,
        service_lines: typing.Optional[typing.List[ServiceLineCreate]] = OMIT,
        external_id: typing.Optional[EncounterExternalId] = OMIT,
        date_of_service: Date,
        end_date_of_service: typing.Optional[Date] = OMIT,
        prior_authorization_number: typing.Optional[PriorAuthorizationNumber] = OMIT,
        patient_authorized_release: bool,
        benefits_assigned_to_provider: bool,
        provider_accepts_assignment: bool,
        appointment_type: typing.Optional[str] = OMIT,
        do_not_bill: typing.Optional[bool] = OMIT,
        existing_medications: typing.Optional[typing.List[Medication]] = OMIT,
        vitals: typing.Optional[Vitals] = OMIT,
        interventions: typing.Optional[typing.List[Intervention]] = OMIT,
        pay_to_address: typing.Optional[StreetAddressLongZip] = OMIT,
        synchronicity: typing.Optional[SynchronicityType] = OMIT,
    ) -> Encounter:
        _request: typing.Dict[str, typing.Any] = {
            "patient": patient,
            "billing_provider": billing_provider,
            "rendering_provider": rendering_provider,
            "diagnoses": diagnoses,
            "place_of_service_code": place_of_service_code,
            "date_of_service": date_of_service,
            "patient_authorized_release": patient_authorized_release,
            "benefits_assigned_to_provider": benefits_assigned_to_provider,
            "provider_accepts_assignment": provider_accepts_assignment,
        }
        if referring_provider is not OMIT:
            _request["referring_provider"] = referring_provider
        if service_facility is not OMIT:
            _request["service_facility"] = service_facility
        if subscriber_primary is not OMIT:
            _request["subscriber_primary"] = subscriber_primary
        if subscriber_secondary is not OMIT:
            _request["subscriber_secondary"] = subscriber_secondary
        if clinical_notes is not OMIT:
            _request["clinical_notes"] = clinical_notes
        if billing_notes is not OMIT:
            _request["billing_notes"] = billing_notes
        if patient_histories is not OMIT:
            _request["patient_histories"] = patient_histories
        if service_lines is not OMIT:
            _request["service_lines"] = service_lines
        if external_id is not OMIT:
            _request["external_id"] = external_id
        if end_date_of_service is not OMIT:
            _request["end_date_of_service"] = end_date_of_service
        if prior_authorization_number is not OMIT:
            _request["prior_authorization_number"] = prior_authorization_number
        if appointment_type is not OMIT:
            _request["appointment_type"] = appointment_type
        if do_not_bill is not OMIT:
            _request["do_not_bill"] = do_not_bill
        if existing_medications is not OMIT:
            _request["existing_medications"] = existing_medications
        if vitals is not OMIT:
            _request["vitals"] = vitals
        if interventions is not OMIT:
            _request["interventions"] = interventions
        if pay_to_address is not OMIT:
            _request["pay_to_address"] = pay_to_address
        if synchronicity is not OMIT:
            _request["synchronicity"] = synchronicity
        async with httpx.AsyncClient() as _client:
            _response = await _client.request(
                "POST",
                urllib.parse.urljoin(f"{self._environment.value}/", "api/encounters/v4"),
                json=jsonable_encoder(_request),
                headers=remove_none_from_headers(
                    {"Authorization": f"Bearer {self._token}" if self._token is not None else None}
                ),
                timeout=60,
            )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(Encounter, _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def update(
        self,
        encounter_id: EncounterId,
        *,
        prior_authorization_number: typing.Optional[PriorAuthorizationNumber] = OMIT,
        external_id: typing.Optional[EncounterExternalId] = OMIT,
        date_of_service: typing.Optional[Date] = OMIT,
        diagnosis_ids: typing.Optional[typing.List[DiagnosisId]] = OMIT,
        tag_ids: typing.Optional[typing.List[TagId]] = OMIT,
        clinical_notes: typing.Optional[typing.List[ClinicalNoteCategoryCreate]] = OMIT,
        pay_to_address: typing.Optional[StreetAddressLongZip] = OMIT,
    ) -> Encounter:
        _request: typing.Dict[str, typing.Any] = {}
        if prior_authorization_number is not OMIT:
            _request["prior_authorization_number"] = prior_authorization_number
        if external_id is not OMIT:
            _request["external_id"] = external_id
        if date_of_service is not OMIT:
            _request["date_of_service"] = date_of_service
        if diagnosis_ids is not OMIT:
            _request["diagnosis_ids"] = diagnosis_ids
        if tag_ids is not OMIT:
            _request["tag_ids"] = tag_ids
        if clinical_notes is not OMIT:
            _request["clinical_notes"] = clinical_notes
        if pay_to_address is not OMIT:
            _request["pay_to_address"] = pay_to_address
        async with httpx.AsyncClient() as _client:
            _response = await _client.request(
                "PATCH",
                urllib.parse.urljoin(f"{self._environment.value}/", f"api/encounters/v4/{encounter_id}"),
                json=jsonable_encoder(_request),
                headers=remove_none_from_headers(
                    {"Authorization": f"Bearer {self._token}" if self._token is not None else None}
                ),
                timeout=60,
            )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(Encounter, _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_attachments(self, encounter_id: EncounterId) -> typing.List[EncounterAttachment]:
        async with httpx.AsyncClient() as _client:
            _response = await _client.request(
                "GET",
                urllib.parse.urljoin(f"{self._environment.value}/", f"api/encounters/v4/{encounter_id}/attachments"),
                headers=remove_none_from_headers(
                    {"Authorization": f"Bearer {self._token}" if self._token is not None else None}
                ),
                timeout=60,
            )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.List[EncounterAttachment], _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def generate_clinical_notes_pdf(self, encounter_id: EncounterId) -> GenerateClinicalNotesPdfResponse:
        async with httpx.AsyncClient() as _client:
            _response = await _client.request(
                "POST",
                urllib.parse.urljoin(
                    f"{self._environment.value}/", f"api/encounters/v4/{encounter_id}/clinical-notes-pdf/generate"
                ),
                headers=remove_none_from_headers(
                    {"Authorization": f"Bearer {self._token}" if self._token is not None else None}
                ),
                timeout=60,
            )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(GenerateClinicalNotesPdfResponse, _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def recompute_network_status_results(self, encounter_id: EncounterId) -> NetworkStatusComputationResults:
        async with httpx.AsyncClient() as _client:
            _response = await _client.request(
                "PUT",
                urllib.parse.urljoin(
                    f"{self._environment.value}/", f"api/encounters/v4/{encounter_id}/network-status-results"
                ),
                headers=remove_none_from_headers(
                    {"Authorization": f"Bearer {self._token}" if self._token is not None else None}
                ),
                timeout=60,
            )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(NetworkStatusComputationResults, _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def mark_as_not_billable(self, encounter_id: EncounterId) -> MarkAsNotBillableResponse:
        async with httpx.AsyncClient() as _client:
            _response = await _client.request(
                "PUT",
                urllib.parse.urljoin(
                    f"{self._environment.value}/", f"api/encounters/v4/{encounter_id}/mark-as-not-billable"
                ),
                headers=remove_none_from_headers(
                    {"Authorization": f"Bearer {self._token}" if self._token is not None else None}
                ),
                timeout=60,
            )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(MarkAsNotBillableResponse, _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)
