# 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
from typing import List as PyList, Literal

from fhirschemapy.R4B.base import (
    Annotation,
    BackboneElement,
    CodeableConcept,
    Identifier,
    Quantity,
    Ratio,
    Reference,
    Timing,
)
from fhirschemapy.R4B.domain_resource import DomainResource


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

    additive_product_name: str | None = Field(
        None, alias="additiveProductName", serialization_alias="additiveProductName"
    )
    additive_type: CodeableConcept | None = Field(
        None, alias="additiveType", serialization_alias="additiveType"
    )
    administration: PyList[NutritionOrderEnteralFormulaAdministration] | None = Field(
        None, alias="administration", serialization_alias="administration"
    )
    administration_instruction: str | None = Field(
        None,
        alias="administrationInstruction",
        serialization_alias="administrationInstruction",
    )
    base_formula_product_name: str | None = Field(
        None,
        alias="baseFormulaProductName",
        serialization_alias="baseFormulaProductName",
    )
    base_formula_type: CodeableConcept | None = Field(
        None, alias="baseFormulaType", serialization_alias="baseFormulaType"
    )
    caloric_density: Quantity | None = Field(
        None, alias="caloricDensity", serialization_alias="caloricDensity"
    )
    max_volume_to_deliver: Quantity | None = Field(
        None, alias="maxVolumeToDeliver", serialization_alias="maxVolumeToDeliver"
    )
    routeof_administration: CodeableConcept | None = Field(
        None, alias="routeofAdministration", serialization_alias="routeofAdministration"
    )


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

    quantity: Quantity | None = Field(
        None, alias="quantity", serialization_alias="quantity"
    )
    rate_quantity: Quantity | None = Field(
        None, alias="rateQuantity", serialization_alias="rateQuantity"
    )
    rate_ratio: Ratio | None = Field(
        None, alias="rateRatio", serialization_alias="rateRatio"
    )
    schedule: Timing | None = Field(
        None, alias="schedule", serialization_alias="schedule"
    )


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

    fluid_consistency_type: PyList[CodeableConcept] | None = Field(
        None, alias="fluidConsistencyType", serialization_alias="fluidConsistencyType"
    )
    instruction: str | None = Field(
        None, alias="instruction", serialization_alias="instruction"
    )
    nutrient: PyList[NutritionOrderOralDietNutrient] | None = Field(
        None, alias="nutrient", serialization_alias="nutrient"
    )
    schedule: PyList[Timing] | None = Field(
        None, alias="schedule", serialization_alias="schedule"
    )
    texture: PyList[NutritionOrderOralDietTexture] | None = Field(
        None, alias="texture", serialization_alias="texture"
    )
    type: PyList[CodeableConcept] | None = Field(
        None, alias="type", serialization_alias="type"
    )


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

    amount: Quantity | None = Field(None, alias="amount", serialization_alias="amount")
    modifier: CodeableConcept | None = Field(
        None, alias="modifier", serialization_alias="modifier"
    )


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

    food_type: CodeableConcept | None = Field(
        None, alias="foodType", serialization_alias="foodType"
    )
    modifier: CodeableConcept | None = Field(
        None, alias="modifier", serialization_alias="modifier"
    )


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

    instruction: str | None = Field(
        None, alias="instruction", serialization_alias="instruction"
    )
    product_name: str | None = Field(
        None, alias="productName", serialization_alias="productName"
    )
    quantity: Quantity | None = Field(
        None, alias="quantity", serialization_alias="quantity"
    )
    schedule: PyList[Timing] | None = Field(
        None, alias="schedule", serialization_alias="schedule"
    )
    type: CodeableConcept | None = Field(None, alias="type", serialization_alias="type")


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

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

    allergy_intolerance: PyList[Reference] | None = Field(
        None, alias="allergyIntolerance", serialization_alias="allergyIntolerance"
    )
    date_time: str = Field(alias="dateTime", serialization_alias="dateTime")
    encounter: Reference | None = Field(
        None, alias="encounter", serialization_alias="encounter"
    )
    enteral_formula: NutritionOrderEnteralFormula | None = Field(
        None, alias="enteralFormula", serialization_alias="enteralFormula"
    )
    exclude_food_modifier: PyList[CodeableConcept] | None = Field(
        None, alias="excludeFoodModifier", serialization_alias="excludeFoodModifier"
    )
    food_preference_modifier: PyList[CodeableConcept] | None = Field(
        None,
        alias="foodPreferenceModifier",
        serialization_alias="foodPreferenceModifier",
    )
    identifier: PyList[Identifier] | None = Field(
        None, alias="identifier", serialization_alias="identifier"
    )
    instantiates: PyList[str] | None = Field(
        None, alias="instantiates", serialization_alias="instantiates"
    )
    instantiates_canonical: PyList[str] | None = Field(
        None, alias="instantiatesCanonical", serialization_alias="instantiatesCanonical"
    )
    instantiates_uri: PyList[str] | None = Field(
        None, alias="instantiatesUri", serialization_alias="instantiatesUri"
    )
    intent: Literal[
        "proposal",
        "plan",
        "directive",
        "order",
        "option",
        "original-order",
        "reflex-order",
        "filler-order",
        "instance-order",
    ] = Field(alias="intent", serialization_alias="intent")
    note: PyList[Annotation] | None = Field(
        None, alias="note", serialization_alias="note"
    )
    oral_diet: NutritionOrderOralDiet | None = Field(
        None, alias="oralDiet", serialization_alias="oralDiet"
    )
    orderer: Reference | None = Field(
        None, alias="orderer", serialization_alias="orderer"
    )
    patient: Reference = Field(alias="patient", serialization_alias="patient")
    status: Literal[
        "draft",
        "active",
        "on-hold",
        "revoked",
        "completed",
        "entered-in-error",
        "unknown",
    ] = Field(alias="status", serialization_alias="status")
    supplement: PyList[NutritionOrderSupplement] | None = Field(
        None, alias="supplement", serialization_alias="supplement"
    )

    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) -> NutritionOrder:
        return cls.model_validate_json(json)
