"""Representative Cora contract boundary models.

The OpenAPI tree included in this package is the source of truth. These models
cover common backend-facing envelopes and literature entities used by smoke
checks and typed boundary imports.
"""

from __future__ import annotations

from pydantic import BaseModel, ConfigDict, Field


class _ContractModel(BaseModel):
    model_config = ConfigDict(extra="forbid")


class ApiError(_ContractModel):
    code: str = Field(min_length=1)
    message: str = Field(min_length=1)
    field: str | None = Field(default=None, min_length=1)


class SuccessMeta(_ContractModel):
    request_id: str | None = Field(default=None, min_length=1)


class LiteratureArticle(_ContractModel):
    articleId: str = Field(min_length=1)
    source: str = Field(min_length=1)
    title: str = Field(min_length=1)
    authors: list[str]
    abstractText: str
    hasAbstract: bool
    publicationTypes: list[str]
    pmid: str | None = Field(default=None, min_length=1)
    pmcid: str | None = Field(default=None, min_length=1)
    doi: str | None = Field(default=None, min_length=1)
    journal: str | None = Field(default=None, min_length=1)
    issn: str | None = Field(default=None, min_length=1)
    eissn: str | None = Field(default=None, min_length=1)
    publicationDate: str | None = Field(default=None, min_length=1)
    keywords: list[str] | None = None
    relatedLinks: list[str] | None = None
    citation: str | None = Field(default=None, min_length=1)
    journalImpactFactor: float | None = Field(default=None, ge=0)
    journalQuartile: str | None = Field(default=None, min_length=1)
    casPartition: str | None = Field(default=None, min_length=1)


class LiteratureSearchResponse(_ContractModel):
    articles: list[LiteratureArticle]
    total: int = Field(ge=0)
    page: int = Field(ge=1)
    pageSize: int = Field(ge=1)

