"""
CASE Response Types

Pydantic models for CASE API responses.
"""

from __future__ import annotations

from typing import Any

from pydantic import BaseModel, Field


class LinkURI(BaseModel):
    """URI reference with sourced ID and title."""

    sourced_id: str = Field(alias="sourcedId")
    title: str
    uri: str

    model_config = {"populate_by_name": True}


class OptionalLinkURI(BaseModel):
    """URI reference with optional uri field."""

    sourced_id: str = Field(alias="sourcedId")
    title: str
    uri: str | None = None

    model_config = {"populate_by_name": True}


class CFDocument(BaseModel):
    """CASE Framework Document response model."""

    sourced_id: str = Field(alias="sourcedId")
    title: str
    uri: str
    framework_type: str | None = Field(None, alias="frameworkType")
    case_version: str | None = Field(None, alias="caseVersion")
    creator: str
    last_change_date_time: str = Field(alias="lastChangeDateTime")
    official_source_url: str | None = Field(None, alias="officialSourceURL")
    publisher: str | None = None
    description: str | None = None
    subject: list[str] | None = None
    subject_uri: list[OptionalLinkURI] | None = Field(None, alias="subjectURI")
    language: str | None = None
    version: str | None = None
    adoption_status: str | None = Field(None, alias="adoptionStatus")
    status_start_date: str | None = Field(None, alias="statusStartDate")
    status_end_date: str | None = Field(None, alias="statusEndDate")
    license_uri: OptionalLinkURI | None = Field(None, alias="licenseURI")
    notes: str | None = None
    extensions: dict[str, Any] | None = None
    cf_package_uri: LinkURI = Field(alias="CFPackageURI")

    model_config = {"populate_by_name": True}


class CFItem(BaseModel):
    """CASE Framework Item response model."""

    sourced_id: str = Field(alias="sourcedId")
    full_statement: str = Field(alias="fullStatement")
    alternative_label: str | None = Field(None, alias="alternativeLabel")
    cf_item_type: str = Field(alias="CFItemType")
    uri: str
    human_coding_scheme: str | None = Field(None, alias="humanCodingScheme")
    list_enumeration: str | None = Field(None, alias="listEnumeration")
    abbreviated_statement: str | None = Field(None, alias="abbreviatedStatement")
    concept_keywords: list[str] | None = Field(None, alias="conceptKeywords")
    concept_keywords_uri: OptionalLinkURI | None = Field(None, alias="conceptKeywordsURI")
    notes: str | None = None
    subject: list[str] | None = None
    subject_uri: list[OptionalLinkURI] | None = Field(None, alias="subjectURI")
    language: str | None = None
    education_level: list[str] | None = Field(None, alias="educationLevel")
    cf_item_type_uri: OptionalLinkURI | None = Field(None, alias="CFItemTypeURI")
    license_uri: OptionalLinkURI | None = Field(None, alias="licenseURI")
    status_start_date: str | None = Field(None, alias="statusStartDate")
    status_end_date: str | None = Field(None, alias="statusEndDate")
    last_change_date_time: str = Field(alias="lastChangeDateTime")
    extensions: dict[str, Any] | None = None
    cf_document_uri: OptionalLinkURI | None = Field(None, alias="CFDocumentURI")

    model_config = {"populate_by_name": True}


class CFAssociation(BaseModel):
    """CASE Framework Association response model."""

    sourced_id: str = Field(alias="sourcedId")
    association_type: str = Field(alias="associationType")
    sequence_number: int | None = Field(None, alias="sequenceNumber")
    uri: str
    origin_node_uri: LinkURI = Field(alias="originNodeURI")
    destination_node_uri: LinkURI = Field(alias="destinationNodeURI")
    cf_association_grouping_uri: OptionalLinkURI | None = Field(
        None, alias="CFAssociationGroupingURI"
    )
    last_change_date_time: str = Field(alias="lastChangeDateTime")
    notes: str | None = None
    extensions: dict[str, Any] | None = None
    cf_document_uri: OptionalLinkURI | None = Field(None, alias="CFDocumentURI")

    model_config = {"populate_by_name": True}


class CFPackage(BaseModel):
    """CASE Framework Package response model."""

    sourced_id: str = Field(alias="sourcedId")
    cf_document: CFDocument = Field(alias="CFDocument")
    cf_items: list[CFItem] | None = Field(None, alias="CFItems")
    cf_associations: list[CFAssociation] | None = Field(None, alias="CFAssociations")

    model_config = {"populate_by_name": True}


class CFItemWithChildGroups(CFItem):
    """CFItem with optional hierarchical child groups."""

    child_groups: dict[str, Any] | None = Field(None, alias="childGroups")

    model_config = {"populate_by_name": True}


class CFPackageWithGroups(BaseModel):
    """CASE Package with hierarchical group structure."""

    sourced_id: str = Field(alias="sourcedId")
    cf_document: CFDocument = Field(alias="CFDocument")
    structured_content: dict[str, list[CFItemWithChildGroups]] | None = Field(
        default=None, alias="structuredContent"
    )

    model_config = {"populate_by_name": True}


class CFPackageUploadResultStats(BaseModel):
    """Upload statistics for a CASE package."""

    documents: int
    items: int
    associations: int


class CFPackageUploadResultDetail(BaseModel):
    """Detailed result of a CASE package upload."""

    document_id: str = Field(alias="documentId")
    stats: CFPackageUploadResultStats
    success: bool

    model_config = {"populate_by_name": True}


class CFPackageUploadResult(BaseModel):
    """Result of a CASE package upload operation."""

    success: bool
    message: str
    result: CFPackageUploadResultDetail

    model_config = {"populate_by_name": True}
