# 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 (
    BackboneElement,
    CodeableConcept,
    Identifier,
    Range,
    Reference,
)
from fhirschemapy.R4B.domain_resource import DomainResource


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

    age: Range | None = Field(None, alias="age", serialization_alias="age")
    applies_to: PyList[CodeableConcept] | None = Field(
        None, alias="appliesTo", serialization_alias="appliesTo"
    )
    category: Literal["reference", "critical", "absolute"] | None = Field(
        None, alias="category", serialization_alias="category"
    )
    condition: str | None = Field(
        None, alias="condition", serialization_alias="condition"
    )
    context: CodeableConcept | None = Field(
        None, alias="context", serialization_alias="context"
    )
    gender: Literal["male", "female", "other", "unknown"] | None = Field(
        None, alias="gender", serialization_alias="gender"
    )
    gestational_age: Range | None = Field(
        None, alias="gestationalAge", serialization_alias="gestationalAge"
    )
    range: Range | None = Field(None, alias="range", serialization_alias="range")


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

    conversion_factor: float | None = Field(
        None, alias="conversionFactor", serialization_alias="conversionFactor"
    )
    customary_unit: CodeableConcept | None = Field(
        None, alias="customaryUnit", serialization_alias="customaryUnit"
    )
    decimal_precision: int | None = Field(
        None, alias="decimalPrecision", serialization_alias="decimalPrecision"
    )
    unit: CodeableConcept | None = Field(None, alias="unit", serialization_alias="unit")


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

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

    abnormal_coded_value_set: Reference | None = Field(
        None, alias="abnormalCodedValueSet", serialization_alias="abnormalCodedValueSet"
    )
    category: PyList[CodeableConcept] | None = Field(
        None, alias="category", serialization_alias="category"
    )
    code: CodeableConcept = Field(alias="code", serialization_alias="code")
    critical_coded_value_set: Reference | None = Field(
        None, alias="criticalCodedValueSet", serialization_alias="criticalCodedValueSet"
    )
    identifier: PyList[Identifier] | None = Field(
        None, alias="identifier", serialization_alias="identifier"
    )
    method: CodeableConcept | None = Field(
        None, alias="method", serialization_alias="method"
    )
    multiple_results_allowed: bool | None = Field(
        None,
        alias="multipleResultsAllowed",
        serialization_alias="multipleResultsAllowed",
    )
    normal_coded_value_set: Reference | None = Field(
        None, alias="normalCodedValueSet", serialization_alias="normalCodedValueSet"
    )
    permitted_data_type: (
        PyList[
            Literal[
                "Quantity",
                "CodeableConcept",
                "string",
                "boolean",
                "integer",
                "Range",
                "Ratio",
                "SampledData",
                "time",
                "dateTime",
                "Period",
            ]
        ]
        | None
    ) = Field(None, alias="permittedDataType", serialization_alias="permittedDataType")
    preferred_report_name: str | None = Field(
        None, alias="preferredReportName", serialization_alias="preferredReportName"
    )
    qualified_interval: PyList[ObservationDefinitionQualifiedInterval] | None = Field(
        None, alias="qualifiedInterval", serialization_alias="qualifiedInterval"
    )
    quantitative_details: ObservationDefinitionQuantitativeDetails | None = Field(
        None, alias="quantitativeDetails", serialization_alias="quantitativeDetails"
    )
    valid_coded_value_set: Reference | None = Field(
        None, alias="validCodedValueSet", serialization_alias="validCodedValueSet"
    )

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