# WARNING: This file is autogenerated by FHIR Schema Codegen.
# https://github.com/fhir-schema/fhir-schema-codegen
# Any manual changes made to this file may be overwritten.

from __future__ import annotations
from pydantic import ConfigDict, Field, PositiveInt
from typing import List as PyList, Literal

from fhirschemapy.R4B.base import (
    BackboneElement,
    CodeableConcept,
    Coding,
    Duration,
    Identifier,
    Period,
    Reference,
)
from fhirschemapy.R4B.domain_resource import DomainResource


class EncounterClassHistory(BackboneElement):
    model_config = ConfigDict(serialize_by_alias=True, extra="forbid")

    class_: Coding = Field(alias="class", serialization_alias="class")
    period: Period = Field(alias="period", serialization_alias="period")


class EncounterDiagnosis(BackboneElement):
    model_config = ConfigDict(serialize_by_alias=True, extra="forbid")

    condition: Reference = Field(alias="condition", serialization_alias="condition")
    rank: PositiveInt | None = Field(None, alias="rank", serialization_alias="rank")
    use: CodeableConcept | None = Field(None, alias="use", serialization_alias="use")


class EncounterHospitalization(BackboneElement):
    model_config = ConfigDict(serialize_by_alias=True, extra="forbid")

    admit_source: CodeableConcept | None = Field(
        None, alias="admitSource", serialization_alias="admitSource"
    )
    destination: Reference | None = Field(
        None, alias="destination", serialization_alias="destination"
    )
    diet_preference: PyList[CodeableConcept] | None = Field(
        None, alias="dietPreference", serialization_alias="dietPreference"
    )
    discharge_disposition: CodeableConcept | None = Field(
        None, alias="dischargeDisposition", serialization_alias="dischargeDisposition"
    )
    origin: Reference | None = Field(None, alias="origin", serialization_alias="origin")
    pre_admission_identifier: Identifier | None = Field(
        None,
        alias="preAdmissionIdentifier",
        serialization_alias="preAdmissionIdentifier",
    )
    re_admission: CodeableConcept | None = Field(
        None, alias="reAdmission", serialization_alias="reAdmission"
    )
    special_arrangement: PyList[CodeableConcept] | None = Field(
        None, alias="specialArrangement", serialization_alias="specialArrangement"
    )
    special_courtesy: PyList[CodeableConcept] | None = Field(
        None, alias="specialCourtesy", serialization_alias="specialCourtesy"
    )


class EncounterLocation(BackboneElement):
    model_config = ConfigDict(serialize_by_alias=True, extra="forbid")

    location: Reference = Field(alias="location", serialization_alias="location")
    period: Period | None = Field(None, alias="period", serialization_alias="period")
    physical_type: CodeableConcept | None = Field(
        None, alias="physicalType", serialization_alias="physicalType"
    )
    status: Literal["planned", "active", "reserved", "completed"] | None = Field(
        None, alias="status", serialization_alias="status"
    )


class EncounterParticipant(BackboneElement):
    model_config = ConfigDict(serialize_by_alias=True, extra="forbid")

    individual: Reference | None = Field(
        None, alias="individual", serialization_alias="individual"
    )
    period: Period | None = Field(None, alias="period", serialization_alias="period")
    type: PyList[CodeableConcept] | None = Field(
        None, alias="type", serialization_alias="type"
    )


class EncounterStatusHistory(BackboneElement):
    model_config = ConfigDict(serialize_by_alias=True, extra="forbid")

    period: Period = Field(alias="period", serialization_alias="period")
    status: Literal[
        "planned",
        "arrived",
        "triaged",
        "in-progress",
        "onleave",
        "finished",
        "cancelled",
        "entered-in-error",
        "unknown",
    ] = Field(alias="status", serialization_alias="status")


class Encounter(DomainResource):
    model_config = ConfigDict(serialize_by_alias=True, extra="forbid")

    resource_type: str = Field(
        default="Encounter",
        alias="resourceType",
        serialization_alias="resourceType",
        frozen=True,
        pattern="Encounter",
    )

    account: PyList[Reference] | None = Field(
        None, alias="account", serialization_alias="account"
    )
    appointment: PyList[Reference] | None = Field(
        None, alias="appointment", serialization_alias="appointment"
    )
    based_on: PyList[Reference] | None = Field(
        None, alias="basedOn", serialization_alias="basedOn"
    )
    class_: Coding = Field(alias="class", serialization_alias="class")
    class_history: PyList[EncounterClassHistory] | None = Field(
        None, alias="classHistory", serialization_alias="classHistory"
    )
    diagnosis: PyList[EncounterDiagnosis] | None = Field(
        None, alias="diagnosis", serialization_alias="diagnosis"
    )
    episode_of_care: PyList[Reference] | None = Field(
        None, alias="episodeOfCare", serialization_alias="episodeOfCare"
    )
    hospitalization: EncounterHospitalization | None = Field(
        None, alias="hospitalization", serialization_alias="hospitalization"
    )
    identifier: PyList[Identifier] | None = Field(
        None, alias="identifier", serialization_alias="identifier"
    )
    length: Duration | None = Field(None, alias="length", serialization_alias="length")
    location: PyList[EncounterLocation] | None = Field(
        None, alias="location", serialization_alias="location"
    )
    participant: PyList[EncounterParticipant] | None = Field(
        None, alias="participant", serialization_alias="participant"
    )
    part_of: Reference | None = Field(
        None, alias="partOf", serialization_alias="partOf"
    )
    period: Period | None = Field(None, alias="period", serialization_alias="period")
    priority: CodeableConcept | None = Field(
        None, alias="priority", serialization_alias="priority"
    )
    reason_code: PyList[CodeableConcept] | None = Field(
        None, alias="reasonCode", serialization_alias="reasonCode"
    )
    reason_reference: PyList[Reference] | None = Field(
        None, alias="reasonReference", serialization_alias="reasonReference"
    )
    service_provider: Reference | None = Field(
        None, alias="serviceProvider", serialization_alias="serviceProvider"
    )
    service_type: CodeableConcept | None = Field(
        None, alias="serviceType", serialization_alias="serviceType"
    )
    status: Literal[
        "planned",
        "arrived",
        "triaged",
        "in-progress",
        "onleave",
        "finished",
        "cancelled",
        "entered-in-error",
        "unknown",
    ] = Field(alias="status", serialization_alias="status")
    status_history: PyList[EncounterStatusHistory] | None = Field(
        None, alias="statusHistory", serialization_alias="statusHistory"
    )
    subject: Reference | None = Field(
        None, alias="subject", serialization_alias="subject"
    )
    type: PyList[CodeableConcept] | None = Field(
        None, alias="type", serialization_alias="type"
    )

    def to_json(self, indent: int | None = None) -> str:
        return self.model_dump_json(
            exclude_unset=True, exclude_none=True, indent=indent
        )

    @classmethod
    def from_json(cls, json: str) -> Encounter:
        return cls.model_validate_json(json)
