"""Tests for screening Pydantic schemas."""
import pytest
from pydantic import ValidationError

from crystallise.screening.schemas import (
    IncludeRating,
    IncludeResponse,
    ReasoningResponse,
    build_cluster_schema,
    build_cluster_selection_schema,
)


class TestIncludeResponse:
    def test_validates_correctly(self):
        resp = IncludeResponse(include_rating=IncludeRating.DEFINITELY_INCLUDE)
        assert resp.include_rating == 5

    def test_all_ratings(self):
        for val in (1, 2, 3, 4, 5):
            resp = IncludeResponse(include_rating=val)
            assert resp.include_rating == val

    def test_invalid_rating_rejected(self):
        with pytest.raises(ValidationError):
            IncludeResponse(include_rating=0)

    def test_invalid_rating_too_high(self):
        with pytest.raises(ValidationError):
            IncludeResponse(include_rating=6)


class TestReasoningResponse:
    def test_validates_correctly(self):
        resp = ReasoningResponse(rating_reasoning="This paper is relevant because...")
        assert resp.rating_reasoning == "This paper is relevant because..."

    def test_empty_reasoning(self):
        resp = ReasoningResponse(rating_reasoning="")
        assert resp.rating_reasoning == ""


class TestBuildClusterSchema:
    def test_creates_valid_model(self):
        criteria_keys = ["Population", "Intervention", "Outcome"]
        ClusterResponse = build_cluster_schema(criteria_keys)
        assert ClusterResponse is not None
        # Verify the model can be instantiated
        instance = ClusterResponse(
            cluster_list=[
                {
                    "cluster_name": "Test Cluster",
                    "cluster_description": "A test cluster",
                    "related_criteria": "Population",
                }
            ]
        )
        assert len(instance.cluster_list) == 1
        assert instance.cluster_list[0].cluster_name == "Test Cluster"

    def test_includes_other_option(self):
        """'Other' is always added to criteria keys."""
        ClusterResponse = build_cluster_schema(["Population"])
        instance = ClusterResponse(
            cluster_list=[
                {
                    "cluster_name": "Misc",
                    "cluster_description": "Miscellaneous",
                    "related_criteria": "Other",
                }
            ]
        )
        assert instance.cluster_list[0].related_criteria.value == "Other"

    def test_invalid_criteria_rejected(self):
        ClusterResponse = build_cluster_schema(["Population"])
        with pytest.raises(ValidationError):
            ClusterResponse(
                cluster_list=[
                    {
                        "cluster_name": "Bad",
                        "cluster_description": "Bad cluster",
                        "related_criteria": "NotACriteria",
                    }
                ]
            )


class TestBuildClusterSelectionSchema:
    def test_creates_valid_model(self):
        ClusterSelectionResponse = build_cluster_selection_schema()
        assert ClusterSelectionResponse is not None
        instance = ClusterSelectionResponse(cluster_list=[1, 2, 3])
        assert instance.cluster_list == [1, 2, 3]

    def test_empty_list(self):
        ClusterSelectionResponse = build_cluster_selection_schema()
        instance = ClusterSelectionResponse(cluster_list=[])
        assert instance.cluster_list == []
