"""Tests for VA-Spec models."""

from __future__ import annotations

from ai4gh.specs.va_spec.models import (
    Agent,
    Classification,
    Contribution,
    Direction,
    Document,
    EvidenceLevel,
    EvidenceLine,
    Method,
    Statement,
)


class TestDirection:
    def test_enum_values(self) -> None:
        assert Direction.SUPPORTS == "supports"
        assert Direction.DISPUTES == "disputes"
        assert Direction.UNCERTAIN == "uncertain"


class TestClassification:
    def test_enum_values(self) -> None:
        assert Classification.PATHOGENIC == "pathogenic"
        assert Classification.LIKELY_PATHOGENIC == "likely_pathogenic"
        assert Classification.UNCERTAIN_SIGNIFICANCE == "uncertain_significance"
        assert Classification.LIKELY_BENIGN == "likely_benign"
        assert Classification.BENIGN == "benign"


class TestEvidenceLevel:
    def test_enum_values(self) -> None:
        assert EvidenceLevel.VERY_STRONG == "very_strong"
        assert EvidenceLevel.STRONG == "strong"
        assert EvidenceLevel.MODERATE == "moderate"
        assert EvidenceLevel.SUPPORTING == "supporting"


class TestAgent:
    def test_minimal(self) -> None:
        agent = Agent()
        assert agent.type == "Agent"
        assert agent.label is None

    def test_full(self) -> None:
        agent = Agent(
            id="agent:001",
            label="ClinVar Expert Panel",
            description="ACMG expert panel",
        )
        assert agent.id == "agent:001"


class TestContribution:
    def test_minimal(self) -> None:
        contrib = Contribution()
        assert contrib.type == "Contribution"

    def test_full(self) -> None:
        contrib = Contribution(
            contributor=Agent(label="Alice Smith"),
            date="2024-01-15",
            activity="interpretation",
        )
        assert contrib.contributor.label == "Alice Smith"
        assert contrib.date == "2024-01-15"


class TestMethod:
    def test_minimal(self) -> None:
        method = Method()
        assert method.type == "Method"

    def test_full(self) -> None:
        method = Method(
            id="method:acmg-2015",
            label="ACMG/AMP 2015 Guidelines",
            url="https://doi.org/10.1038/gim.2015.30",
            version="2015",
        )
        assert method.id == "method:acmg-2015"


class TestDocument:
    def test_minimal(self) -> None:
        doc = Document()
        assert doc.type == "Document"

    def test_full(self) -> None:
        doc = Document(
            id="PMID:25741868",
            label="Richards et al. 2015",
            url="https://pubmed.ncbi.nlm.nih.gov/25741868/",
            pmid="25741868",
            doi="10.1038/gim.2015.30",
        )
        assert doc.pmid == "25741868"
        assert doc.doi == "10.1038/gim.2015.30"


class TestEvidenceLine:
    def test_minimal(self) -> None:
        el = EvidenceLine()
        assert el.type == "EvidenceLine"
        assert el.direction is None

    def test_full(self) -> None:
        el = EvidenceLine(
            id="ev:001",
            direction=Direction.SUPPORTS,
            strength=EvidenceLevel.STRONG,
            description="Functional studies show loss of protein function",
            evidence_items=[Document(pmid="12345678", label="Smith et al. 2024")],
            contributions=[
                Contribution(
                    contributor=Agent(label="Alice"),
                    date="2024-01-15",
                )
            ],
        )
        assert el.direction is Direction.SUPPORTS
        assert el.strength is EvidenceLevel.STRONG
        assert len(el.evidence_items) == 1
        assert len(el.contributions) == 1


class TestStatement:
    def test_minimal(self) -> None:
        stmt = Statement()
        assert stmt.type == "Statement"
        assert stmt.classification is None

    def test_full(self) -> None:
        stmt = Statement(
            id="stmt:001",
            subject="ga4gh:VA.abc123",
            predicate="is_classified_as",
            object_descriptor="pathogenic",
            classification=Classification.PATHOGENIC,
            direction=Direction.SUPPORTS,
            description="BRCA1 c.68_69del classified as pathogenic",
            evidence_lines=[
                EvidenceLine(
                    direction=Direction.SUPPORTS,
                    strength=EvidenceLevel.VERY_STRONG,
                )
            ],
            method=Method(label="ACMG/AMP 2015"),
            contributions=[
                Contribution(
                    contributor=Agent(label="Expert Panel"),
                    date="2024-06-01",
                )
            ],
            specified_by=Method(
                label="VCEP Rules",
                url="https://example.com/vcep",
            ),
        )
        assert stmt.classification is Classification.PATHOGENIC
        assert len(stmt.evidence_lines) == 1
        assert stmt.method.label == "ACMG/AMP 2015"
        assert stmt.specified_by.url == "https://example.com/vcep"

    def test_from_dict(self) -> None:
        stmt = Statement.model_validate(
            {
                "subject": "variant-1",
                "classification": "benign",
                "direction": "disputes",
            }
        )
        assert stmt.classification is Classification.BENIGN
        assert stmt.direction is Direction.DISPUTES

    def test_extra_fields(self) -> None:
        stmt = Statement.model_validate({"custom_annotation": "value"})
        assert stmt.custom_annotation == "value"
