"""Tests for ConsistencyCheck."""

from __future__ import annotations

from unittest.mock import MagicMock, patch

from ai_qa.checks.consistency import ConsistencyCheck
from ai_qa.core.context import Context


def test_consistency_check_name():
    """Test ConsistencyCheck has correct name."""
    check = ConsistencyCheck()
    assert check.name == "consistency"


def test_consistency_check_requires_llm():
    """Test ConsistencyCheck requires LLM."""
    check = ConsistencyCheck()
    assert check.requires_llm is True


@patch("ai_qa.checks.consistency.get_provider")
def test_consistency_check_consistent_output(mock_get_provider):
    """Test ConsistencyCheck with fully consistent output."""
    mock_provider = MagicMock()
    mock_provider.judge.return_value = {
        "score": 1.0,
        "evidence": "Output is internally consistent",
    }
    mock_get_provider.return_value = mock_provider

    check = ConsistencyCheck()
    ctx = Context(
        output="The project will take 2 weeks. We estimate 14 days total."
    )
    result = check.evaluate(ctx)

    assert result.passed is True
    assert result.score == 1.0


@patch("ai_qa.checks.consistency.get_provider")
def test_consistency_check_contradictory_output(mock_get_provider):
    """Test ConsistencyCheck with contradictory output."""
    mock_provider = MagicMock()
    mock_provider.judge.return_value = {
        "score": 0.1,
        "evidence": "Contradiction: claims both 'yes' and 'no'",
    }
    mock_get_provider.return_value = mock_provider

    check = ConsistencyCheck()
    ctx = Context(output="The answer is yes. The answer is no.")
    result = check.evaluate(ctx)

    assert result.passed is False
    assert result.score == 0.1


@patch("ai_qa.checks.consistency.get_provider")
def test_consistency_check_with_conversation_history(mock_get_provider):
    """Test ConsistencyCheck with conversation history."""
    mock_provider = MagicMock()
    mock_provider.judge.return_value = {"score": 0.8, "evidence": "OK"}
    mock_get_provider.return_value = mock_provider

    check = ConsistencyCheck()
    ctx = Context(
        output="The user's name is Alice",
        conversation=[
            {"role": "user", "content": "My name is Alice"},
            {"role": "assistant", "content": "Nice to meet you, Alice!"},
        ],
    )
    result = check.evaluate(ctx)

    assert result.score == 0.8


@patch("ai_qa.checks.consistency.get_provider")
def test_consistency_check_conversation_contradiction(mock_get_provider):
    """Test ConsistencyCheck detects contradiction with conversation history."""
    mock_provider = MagicMock()
    mock_provider.judge.return_value = {
        "score": 0.2,
        "evidence": "Contradicts earlier statement: said name was Alice",
    }
    mock_get_provider.return_value = mock_provider

    check = ConsistencyCheck()
    ctx = Context(
        output="Your name is Bob",
        conversation=[
            {"role": "user", "content": "My name is Alice"},
            {"role": "assistant", "content": "Nice to meet you, Alice!"},
        ],
    )
    result = check.evaluate(ctx)

    assert result.passed is False


@patch("ai_qa.checks.consistency.get_provider")
def test_consistency_check_custom_threshold(mock_get_provider):
    """Test ConsistencyCheck with custom threshold."""
    mock_provider = MagicMock()
    mock_provider.judge.return_value = {"score": 0.7, "evidence": "Some issues"}
    mock_get_provider.return_value = mock_provider

    check = ConsistencyCheck(threshold=0.85)
    ctx = Context(output="Test output")
    result = check.evaluate(ctx)

    assert result.passed is False


@patch("ai_qa.checks.consistency.get_provider")
def test_consistency_check_without_conversation(mock_get_provider):
    """Test ConsistencyCheck without conversation history."""
    mock_provider = MagicMock()
    mock_provider.judge.return_value = {"score": 0.95, "evidence": "Consistent"}
    mock_get_provider.return_value = mock_provider

    check = ConsistencyCheck()
    ctx = Context(output="This statement is true and valid.")
    result = check.evaluate(ctx)

    assert result.passed is True
