# 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,
    Period,
    Reference,
)
from fhirschemapy.R4B.domain_resource import DomainResource


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

    collected_date_time: str | None = Field(
        None, alias="collectedDateTime", serialization_alias="collectedDateTime"
    )
    collected_period: Period | None = Field(
        None, alias="collectedPeriod", serialization_alias="collectedPeriod"
    )
    collector: Reference | None = Field(
        None, alias="collector", serialization_alias="collector"
    )
    source: Reference | None = Field(None, alias="source", serialization_alias="source")


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

    description: str | None = Field(
        None, alias="description", serialization_alias="description"
    )
    time_date_time: str | None = Field(
        None, alias="timeDateTime", serialization_alias="timeDateTime"
    )
    time_period: Period | None = Field(
        None, alias="timePeriod", serialization_alias="timePeriod"
    )


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

    additive: Reference | None = Field(
        None, alias="additive", serialization_alias="additive"
    )
    description: str | None = Field(
        None, alias="description", serialization_alias="description"
    )
    procedure: CodeableConcept | None = Field(
        None, alias="procedure", serialization_alias="procedure"
    )
    time_date_time: str | None = Field(
        None, alias="timeDateTime", serialization_alias="timeDateTime"
    )
    time_period: Period | None = Field(
        None, alias="timePeriod", serialization_alias="timePeriod"
    )


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

    description: str | None = Field(
        None, alias="description", serialization_alias="description"
    )
    duration: Period | None = Field(
        None, alias="duration", serialization_alias="duration"
    )
    scale: Literal["farenheit", "celsius", "kelvin"] | None = Field(
        None, alias="scale", serialization_alias="scale"
    )
    temperature: float | None = Field(
        None, alias="temperature", serialization_alias="temperature"
    )


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

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

    collection: BiologicallyDerivedProductCollection | None = Field(
        None, alias="collection", serialization_alias="collection"
    )
    identifier: PyList[Identifier] | None = Field(
        None, alias="identifier", serialization_alias="identifier"
    )
    manipulation: BiologicallyDerivedProductManipulation | None = Field(
        None, alias="manipulation", serialization_alias="manipulation"
    )
    parent: PyList[Reference] | None = Field(
        None, alias="parent", serialization_alias="parent"
    )
    processing: PyList[BiologicallyDerivedProductProcessing] | None = Field(
        None, alias="processing", serialization_alias="processing"
    )
    product_category: (
        Literal["organ", "tissue", "fluid", "cells", "biologicalAgent"] | None
    ) = Field(None, alias="productCategory", serialization_alias="productCategory")
    product_code: CodeableConcept | None = Field(
        None, alias="productCode", serialization_alias="productCode"
    )
    quantity: int | None = Field(None, alias="quantity", serialization_alias="quantity")
    request: PyList[Reference] | None = Field(
        None, alias="request", serialization_alias="request"
    )
    status: Literal["available", "unavailable"] | None = Field(
        None, alias="status", serialization_alias="status"
    )
    storage: PyList[BiologicallyDerivedProductStorage] | None = Field(
        None, alias="storage", serialization_alias="storage"
    )

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