"""
Neontology node schemas for the cc.public.exams knowledge graph.

cc.public.exams is a dedicated, shared, public Neo4j database — co-primary/authoritative for the
exam knowledge graph (specs, spec-points, paper→question→part→region structure, ASSESSES links).
Supabase remains source of truth for operational data (geometry, marks, submissions); the two
layers join on shared UUIDs:

    exam_questions.id        <-> Question|Part.uuid_string   (container -> Question, leaf -> Part)
    exam_response_areas.id   <-> Region.uuid_string
    eb_exams.exam_code       <-> ExamPaper.exam_code
    eb_specifications.spec_code <-> Specification.spec_code

Ownership: created by an infra-init step; read by all authenticated API calls; written by the API
service role only (no direct client writes).
"""
from typing import ClassVar, Optional
from ..base_nodes import CCBaseNode


class ExamBaseNode(CCBaseNode):
    __primarylabel__: ClassVar[str] = ''


class ExamBoardNode(ExamBaseNode):
    __primarylabel__: ClassVar[str] = 'ExamBoard'
    code: str                      # 'AQA'
    name: str


class SpecificationNode(ExamBaseNode):
    __primarylabel__: ClassVar[str] = 'Specification'
    spec_code: str                 # 'AQA-PHYS-8463'  (== Supabase eb_specifications.spec_code)
    exam_board_code: str
    subject_code: Optional[str] = None
    award_code: Optional[str] = None
    title: Optional[str] = None


class SpecPointNode(ExamBaseNode):
    __primarylabel__: ClassVar[str] = 'SpecPoint'
    ref: str                       # '4.1', '4.2.1'
    description: str
    spec_code: str
    exam_board_code: str


class ExamPaperNode(ExamBaseNode):
    __primarylabel__: ClassVar[str] = 'ExamPaper'
    exam_code: str                 # == Supabase eb_exams.exam_code
    spec_code: str
    paper_code: Optional[str] = None
    tier: Optional[str] = None
    session: Optional[str] = None
    title: Optional[str] = None
    page_count: Optional[int] = None


class QuestionNode(ExamBaseNode):  # roll-up container; uuid_string == exam_questions.id
    __primarylabel__: ClassVar[str] = 'Question'
    exam_code: str
    label: str                     # '01'
    order: int
    max_marks: float


class PartNode(ExamBaseNode):      # leaf; uuid_string == exam_questions.id
    __primarylabel__: ClassVar[str] = 'Part'
    exam_code: str
    label: str                     # '01.1'
    order: int
    max_marks: float
    answer_type: str
    mark_scheme_type: str


class RegionNode(ExamBaseNode):    # uuid_string == exam_response_areas.id
    __primarylabel__: ClassVar[str] = 'Region'
    page: int
    kind: str                      # 'response' | 'context'
    response_form: str


# Relationship reference (written by the projection / linker, not modelled as classes here):
#   (:ExamBoard)-[:PUBLISHES]->(:Specification)
#   (:Specification)-[:HAS_SPEC_POINT]->(:SpecPoint)
#   (:Specification)-[:HAS_PAPER]->(:ExamPaper)
#   (:ExamPaper)-[:HAS_QUESTION]->(:Question)
#   (:Question)-[:HAS_PART]->(:Part)        # nested questions allowed
#   (:Part)-[:HAS_REGION]->(:Region)
#   (:Part)-[:ASSESSES]->(:SpecPoint)       # from exam_questions.spec_ref
#   (:SpecPoint)-[:TEACHES]->(:LearningStatement)   # DEFERRED cross-db bridge
