from __future__ import annotations

from typing import Literal

from pydantic import Field

from app.rda.domain.models import DomainModel, RdaArtifactType


class FhirLikeReference(DomainModel):
    reference: str


class FhirLikeBundleEntry(DomainModel):
    full_url: str
    reference: FhirLikeReference


class FhirLikeBundle(DomainModel):
    id: str
    type: Literal["document"] = "document"
    entries: list[FhirLikeBundleEntry] = Field(default_factory=list)


class FhirLikeComposition(DomainModel):
    id: str
    status: Literal["final"] = "final"
    title: str
    subject: FhirLikeReference
    encounter: FhirLikeReference | None = None
    organization_references: list[FhirLikeReference] = Field(default_factory=list)
    practitioner_reference: FhirLikeReference | None = None


class FhirLikePatient(DomainModel):
    id: str
    name: str | None = None
    identifier_type: str | None = None
    identifier_value: str | None = None
    birth_date: str | None = None
    sex: str | None = None


class FhirLikeEncounter(DomainModel):
    id: str
    case_key: str
    case_number: str | None = None
    admission_at: str | None = None
    reason: str | None = None
    triage: str | None = None
    subject: FhirLikeReference
    provider_references: list[FhirLikeReference] = Field(default_factory=list)
    payer_references: list[FhirLikeReference] = Field(default_factory=list)
    practitioner_reference: FhirLikeReference | None = None


class FhirLikeOrganization(DomainModel):
    id: str
    role: Literal["provider", "payer"]
    name: str | None = None
    identifier_value: str | None = None


class FhirLikePractitioner(DomainModel):
    id: str
    name: str


class FhirLikeDocumentReference(DomainModel):
    id: str
    subject: FhirLikeReference | None = None
    description: str | None = None


class RdaFhirProjection(DomainModel):
    artifact_type: RdaArtifactType
    bundle: FhirLikeBundle
    composition: FhirLikeComposition
    patient: FhirLikePatient
    encounter: FhirLikeEncounter | None = None
    organizations: list[FhirLikeOrganization] = Field(default_factory=list)
    practitioner: FhirLikePractitioner | None = None
    document_reference: FhirLikeDocumentReference | None = None
    projection_gaps: list[str] = Field(default_factory=list)
