"""Tests for criteria domain models."""
import pytest
from pydantic import ValidationError

from crystallise.criteria.models import (
    CriterionSource,
    CriterionType,
    DEFAULT_CATEGORIES,
    ExclusionCriterion,
)


class TestExclusionCriterion:
    def test_creates_with_required_fields(self):
        criterion = ExclusionCriterion(
            id=1,
            project_id=1,
            category="Population",
            text="Adults 18+",
        )
        assert criterion.id == 1
        assert criterion.project_id == 1
        assert criterion.category == "Population"
        assert criterion.text == "Adults 18+"

    def test_defaults_are_correct(self):
        criterion = ExclusionCriterion(
            id=1,
            project_id=1,
            category="Population",
            text="Adults 18+",
        )
        assert criterion.is_active is True
        assert criterion.source == CriterionSource.human
        assert criterion.criterion_type == CriterionType.exclude
        assert criterion.description is None
        assert criterion.ai_confidence is None
        assert criterion.ai_rationale is None
        assert criterion.notes is None
        assert criterion.title_abstract_assessable is True
        assert criterion.research_question_links == []

    def test_ai_confidence_validation(self):
        # Valid confidence
        criterion = ExclusionCriterion(
            id=1, project_id=1, category="Pop", text="Test",
            ai_confidence=0.85,
        )
        assert criterion.ai_confidence == 0.85

        # Invalid confidence
        with pytest.raises(ValidationError):
            ExclusionCriterion(
                id=1, project_id=1, category="Pop", text="Test",
                ai_confidence=1.5,
            )

    def test_confidence_percentage(self):
        criterion = ExclusionCriterion(
            id=1, project_id=1, category="Pop", text="Test",
            ai_confidence=0.85,
        )
        assert criterion.confidence_percentage == 85

    def test_is_ai_generated(self):
        human = ExclusionCriterion(
            id=1, project_id=1, category="Pop", text="Test",
            source=CriterionSource.human,
        )
        ai = ExclusionCriterion(
            id=2, project_id=1, category="Pop", text="Test",
            source=CriterionSource.ai_generated,
        )
        assert human.is_ai_generated is False
        assert ai.is_ai_generated is True


class TestCriterionEnums:
    def test_criterion_source_values(self):
        assert CriterionSource.human == "human"
        assert CriterionSource.ai_generated == "ai_generated"

    def test_criterion_type_values(self):
        assert CriterionType.include == "include"
        assert CriterionType.exclude == "exclude"


class TestDefaultCategories:
    def test_contains_standard_pico_categories(self):
        assert "Population" in DEFAULT_CATEGORIES
        assert "Intervention/Exposure" in DEFAULT_CATEGORIES
        assert "Comparator" in DEFAULT_CATEGORIES
        assert "Outcome" in DEFAULT_CATEGORIES
        assert "Study Design" in DEFAULT_CATEGORIES

    def test_has_other_category(self):
        assert "Other" in DEFAULT_CATEGORIES
