from app.services.steward_intent_agent import (
    STEWARD_INTENT_FUNCTION_NAME,
    StewardIntentAgent,
)
from app.schemas.steward import StewardPlanRequest


class _NoToolCallRuntimeChatService:
    def __init__(self) -> None:
        self.kwargs = {}

    def complete_with_tool_call(self, messages, **kwargs):
        self.kwargs = kwargs

        class _Result:
            tool_call = None

            @staticmethod
            def calls_as_dicts():
                return []

        return _Result()


def test_steward_intent_tool_schema_supports_pending_flow_confirmation() -> None:
    schema = StewardIntentAgent._build_intent_tool_schema(
        ["expense_type", "time_range", "location", "reason", "transport_mode"]
    )

    function_schema = schema["function"]
    assert function_schema["name"] == STEWARD_INTENT_FUNCTION_NAME
    properties = function_schema["parameters"]["properties"]
    task_schema = properties["tasks"]["items"]
    pending_schema = properties["pending_flow_confirmation"]
    candidate_schema = pending_schema["properties"]["candidate_flows"]["items"]

    assert task_schema["properties"]["requested_action"]["enum"] == [
        "preview",
        "save_draft",
        "submit",
    ]
    assert "requested_action" in task_schema["required"]
    assert "pending_flow_confirmation" in properties
    assert pending_schema["properties"]["status"]["enum"] == ["none", "pending"]
    assert candidate_schema["properties"]["flow_id"]["enum"] == [
        "travel_application",
        "travel_reimbursement",
    ]
    assert candidate_schema["properties"]["missing_fields"]["items"]["enum"] == [
        "expense_type",
        "time_range",
        "location",
        "reason",
        "transport_mode",
    ]


def test_steward_intent_agent_uses_ten_second_timeout_and_three_attempts() -> None:
    runtime_chat = _NoToolCallRuntimeChatService()
    agent = StewardIntentAgent(runtime_chat)

    agent.detect(
        StewardPlanRequest(message="2026-02-20 至 2026-02-23，上海出差，火车，保存草稿。"),
        base_date=__import__("datetime").date(2026, 6, 24),
        canonical_fields=["expense_type", "time_range", "location", "reason", "transport_mode"],
    )

    assert runtime_chat.kwargs["timeout_seconds"] == 10
    assert runtime_chat.kwargs["max_attempts"] == 3
    assert runtime_chat.kwargs["use_failure_cooldown"] is False


def test_steward_intent_tool_schema_includes_query_task_type_from_registry() -> None:
    """function call schema 的 task_type enum 应从注册表动态生成,包含查询意图。"""
    from app.services import steward_intent_bootstrap  # noqa: F401  触发意图注册

    schema = StewardIntentAgent._build_intent_tool_schema(
        ["expense_type", "time_range", "location", "reason", "transport_mode"]
    )
    task_schema = schema["function"]["parameters"]["properties"]["tasks"]["items"]
    task_type_enum = task_schema["properties"]["task_type"]["enum"]

    assert "expense_application" in task_type_enum
    assert "reimbursement" in task_type_enum
    assert "query_travel_standard" in task_type_enum


def test_steward_intent_system_prompt_mentions_query_intent_guidance() -> None:
    """system prompt 应包含查询意图的识别指引,避免被误识别为申请。"""
    from app.services import steward_intent_bootstrap  # noqa: F401  触发意图注册

    messages = StewardIntentAgent._build_messages(
        StewardPlanRequest(message="武汉出差标准是多少"),
        base_date=__import__("datetime").date(2026, 6, 24),
        canonical_fields=["location", "employee_grade"],
    )
    system_prompt = messages[0]["content"]
    assert "query_travel_standard" in system_prompt
    assert "差旅" in system_prompt
    assert "住宿标准" in system_prompt


def test_steward_intent_system_prompt_includes_conversation_history_guidance() -> None:
    """system prompt 应包含'结合对话历史理解确认类话术'的引导。"""
    from app.services import steward_intent_bootstrap  # noqa: F401

    messages = StewardIntentAgent._build_messages(
        StewardPlanRequest(message="再提交"),
        base_date=__import__("datetime").date(2026, 6, 24),
        canonical_fields=["location", "time_range"],
    )
    system_prompt = messages[0]["content"]
    assert "recent_history" in system_prompt
    assert "再提交" in system_prompt
    assert "确认类话术" in system_prompt


def test_steward_intent_context_payload_includes_recent_history() -> None:
    """context_payload 应携带 recent_history 结构化字段（role + content）。"""
    import json

    request = StewardPlanRequest(
        message="再提交",
        context_json={
            "recent_history": [
                {"role": "user", "content": "2026-02-20 至 2026-02-23，去上海出差，火车"},
                {"role": "assistant", "content": "好的，为您整理出差申请预览。"},
                {"role": "user", "content": "直接提交"},
                {"role": "assistant", "content": "检测到重复申请，已暂停提交。"},
            ],
        },
    )
    messages = StewardIntentAgent._build_messages(
        request,
        base_date=__import__("datetime").date(2026, 6, 24),
        canonical_fields=["location", "time_range"],
    )
    user_payload = json.loads(messages[1]["content"])
    assert "recent_history" in user_payload
    assert len(user_payload["recent_history"]) == 4
    assert user_payload["recent_history"][0]["role"] == "user"
    assert "上海" in user_payload["recent_history"][0]["content"]


def test_steward_intent_context_payload_omits_empty_recent_history() -> None:
    """无 recent_history 时不应注入空列表。"""
    import json

    messages = StewardIntentAgent._build_messages(
        StewardPlanRequest(message="你好"),
        base_date=__import__("datetime").date(2026, 6, 24),
        canonical_fields=["location"],
    )
    user_payload = json.loads(messages[1]["content"])
    assert user_payload.get("recent_history", []) == []
