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


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

    detail: CarePlanActivityDetail | None = Field(
        None, alias="detail", serialization_alias="detail"
    )
    outcome_codeable_concept: PyList[CodeableConcept] | None = Field(
        None,
        alias="outcomeCodeableConcept",
        serialization_alias="outcomeCodeableConcept",
    )
    outcome_reference: PyList[Reference] | None = Field(
        None, alias="outcomeReference", serialization_alias="outcomeReference"
    )
    progress: PyList[Annotation] | None = Field(
        None, alias="progress", serialization_alias="progress"
    )
    reference: Reference | None = Field(
        None, alias="reference", serialization_alias="reference"
    )


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

    code: CodeableConcept | None = Field(None, alias="code", serialization_alias="code")
    daily_amount: Quantity | None = Field(
        None, alias="dailyAmount", serialization_alias="dailyAmount"
    )
    description: str | None = Field(
        None, alias="description", serialization_alias="description"
    )
    do_not_perform: bool | None = Field(
        None, alias="doNotPerform", serialization_alias="doNotPerform"
    )
    goal: PyList[Reference] | None = Field(
        None, alias="goal", serialization_alias="goal"
    )
    instantiates_canonical: PyList[str] | None = Field(
        None, alias="instantiatesCanonical", serialization_alias="instantiatesCanonical"
    )
    instantiates_uri: PyList[str] | None = Field(
        None, alias="instantiatesUri", serialization_alias="instantiatesUri"
    )
    kind: (
        Literal[
            "Appointment",
            "CommunicationRequest",
            "DeviceRequest",
            "MedicationRequest",
            "NutritionOrder",
            "Task",
            "ServiceRequest",
            "VisionPrescription",
        ]
        | None
    ) = Field(None, alias="kind", serialization_alias="kind")
    location: Reference | None = Field(
        None, alias="location", serialization_alias="location"
    )
    performer: PyList[Reference] | None = Field(
        None, alias="performer", serialization_alias="performer"
    )
    product_codeable_concept: CodeableConcept | None = Field(
        None,
        alias="productCodeableConcept",
        serialization_alias="productCodeableConcept",
    )
    product_reference: Reference | None = Field(
        None, alias="productReference", serialization_alias="productReference"
    )
    quantity: Quantity | None = Field(
        None, alias="quantity", serialization_alias="quantity"
    )
    reason_code: PyList[CodeableConcept] | None = Field(
        None, alias="reasonCode", serialization_alias="reasonCode"
    )
    reason_reference: PyList[Reference] | None = Field(
        None, alias="reasonReference", serialization_alias="reasonReference"
    )
    scheduled_period: Period | None = Field(
        None, alias="scheduledPeriod", serialization_alias="scheduledPeriod"
    )
    scheduled_string: str | None = Field(
        None, alias="scheduledString", serialization_alias="scheduledString"
    )
    scheduled_timing: Timing | None = Field(
        None, alias="scheduledTiming", serialization_alias="scheduledTiming"
    )
    status: Literal[
        "not-started",
        "scheduled",
        "in-progress",
        "on-hold",
        "completed",
        "cancelled",
        "unknown",
        "entered-in-error",
        "stopped",
    ] = Field(alias="status", serialization_alias="status")
    status_reason: CodeableConcept | None = Field(
        None, alias="statusReason", serialization_alias="statusReason"
    )


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

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

    activity: PyList[CarePlanActivity] | None = Field(
        None, alias="activity", serialization_alias="activity"
    )
    addresses: PyList[Reference] | None = Field(
        None, alias="addresses", serialization_alias="addresses"
    )
    author: Reference | None = Field(None, alias="author", serialization_alias="author")
    based_on: PyList[Reference] | None = Field(
        None, alias="basedOn", serialization_alias="basedOn"
    )
    care_team: PyList[Reference] | None = Field(
        None, alias="careTeam", serialization_alias="careTeam"
    )
    category: PyList[CodeableConcept] | None = Field(
        None, alias="category", serialization_alias="category"
    )
    contributor: PyList[Reference] | None = Field(
        None, alias="contributor", serialization_alias="contributor"
    )
    created: str | None = Field(None, alias="created", serialization_alias="created")
    description: str | None = Field(
        None, alias="description", serialization_alias="description"
    )
    encounter: Reference | None = Field(
        None, alias="encounter", serialization_alias="encounter"
    )
    goal: PyList[Reference] | None = Field(
        None, alias="goal", serialization_alias="goal"
    )
    identifier: PyList[Identifier] | None = Field(
        None, alias="identifier", serialization_alias="identifier"
    )
    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", "order", "option"] = Field(
        alias="intent", serialization_alias="intent"
    )
    note: PyList[Annotation] | None = Field(
        None, alias="note", serialization_alias="note"
    )
    part_of: PyList[Reference] | None = Field(
        None, alias="partOf", serialization_alias="partOf"
    )
    period: Period | None = Field(None, alias="period", serialization_alias="period")
    replaces: PyList[Reference] | None = Field(
        None, alias="replaces", serialization_alias="replaces"
    )
    status: Literal[
        "draft",
        "active",
        "on-hold",
        "revoked",
        "completed",
        "entered-in-error",
        "unknown",
    ] = Field(alias="status", serialization_alias="status")
    subject: Reference = Field(alias="subject", serialization_alias="subject")
    supporting_info: PyList[Reference] | None = Field(
        None, alias="supportingInfo", serialization_alias="supportingInfo"
    )
    title: str | None = Field(None, alias="title", serialization_alias="title")

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