"""Pydantic 模型校验测试."""

import pytest
from pydantic import ValidationError

from src.ai.models.chat import ChatData, ChatMessage, ChatRequest, Usage
from src.ai.models.expression import OptimizeExpressionRequest
from src.ai.models.question import GeneratedQuestionData, GenerateQuestionRequest
from src.ai.models.workflow import (
    ConfirmRequest,
    LessonPreparationRequest,
    WorkflowStatusData,
)


class TestChatModels:
    """聊天模型测试."""

    def test_chat_message_valid(self) -> None:
        msg = ChatMessage(role="user", content="hello")
        assert msg.role == "user"

    def test_chat_message_empty_content_rejected(self) -> None:
        with pytest.raises(ValidationError):
            ChatMessage(role="user", content="")

    def test_chat_message_invalid_role(self) -> None:
        with pytest.raises(ValidationError):
            ChatMessage(role="invalid", content="text")

    def test_chat_request_defaults(self) -> None:
        req = ChatRequest(messages=[ChatMessage(role="user", content="hi")])
        assert req.model == "gpt-4o-mini"
        assert req.temperature == 0.7
        assert req.stream is False

    def test_chat_request_empty_messages_rejected(self) -> None:
        with pytest.raises(ValidationError):
            ChatRequest(messages=[])

    def test_chat_request_temperature_range(self) -> None:
        with pytest.raises(ValidationError):
            ChatRequest(
                messages=[ChatMessage(role="user", content="hi")],
                temperature=3.0,
            )

    def test_usage_defaults(self) -> None:
        usage = Usage()
        assert usage.prompt_tokens == 0
        assert usage.total_tokens == 0

    def test_chat_data_degraded_fields(self) -> None:
        data = ChatData(
            content="x", model="m", usage=Usage(),
            degraded=True, degraded_reason="test",
        )
        assert data.degraded is True


class TestQuestionModels:
    """题目模型测试."""

    def test_generate_question_request_defaults(self) -> None:
        req = GenerateQuestionRequest(prompt="生成题", subject="数学")
        assert req.difficulty == "medium"
        assert req.question_type == "short_answer"
        assert req.count == 1

    def test_invalid_difficulty(self) -> None:
        with pytest.raises(ValidationError):
            GenerateQuestionRequest(prompt="x", subject="数学", difficulty="impossible")

    def test_invalid_question_type(self) -> None:
        with pytest.raises(ValidationError):
            GenerateQuestionRequest(prompt="x", subject="数学", question_type="invalid")

    def test_count_range(self) -> None:
        with pytest.raises(ValidationError):
            GenerateQuestionRequest(prompt="x", subject="数学", count=0)
        with pytest.raises(ValidationError):
            GenerateQuestionRequest(prompt="x", subject="数学", count=11)

    def test_generated_question_data_defaults(self) -> None:
        data = GeneratedQuestionData(question="q", answer="a", explanation="e")
        assert data.question_type == "short_answer"
        assert data.degraded is False
        assert data.evaluation_score is None


class TestExpressionModels:
    """表达优化模型测试."""

    def test_valid_request(self) -> None:
        req = OptimizeExpressionRequest(text="优化这段")
        assert req.text == "优化这段"
        assert req.context == ""

    def test_empty_text_rejected(self) -> None:
        with pytest.raises(ValidationError):
            OptimizeExpressionRequest(text="")


class TestWorkflowModels:
    """工作流模型测试."""

    def test_lesson_preparation_request_defaults(self) -> None:
        req = LessonPreparationRequest(
            class_id="c-1",
            subject_id="math",
            topic="代数",
        )
        assert req.target_difficulty == "medium"
        assert req.question_count == 5

    def test_question_count_range(self) -> None:
        with pytest.raises(ValidationError):
            LessonPreparationRequest(
                class_id="c-1",
                subject_id="math",
                topic="t",
                question_count=0,
            )

    def test_confirm_request_optional(self) -> None:
        req = ConfirmRequest()
        assert req.modifications is None

    def test_workflow_status_data_defaults(self) -> None:
        data = WorkflowStatusData(workflow_id="wf-1", status="pending")
        assert data.questions == []
        assert data.error is None
        assert data.degraded is False
