from langchain_core.messages import HumanMessage

import app.agents.graph as graph_module
from app.agents.graph import master_node
from app.agents.learning.retrospector import build_session_retrospective
from app.agents.schemas.orchestration import (
    RuntimeRequestContext,
    assess_parallel_worthiness,
    render_runtime_request_context_summary,
)
from app.agents.schemas.skills import SkillShortlistEntry
from app.agents.state import initial_state


def test_runtime_request_context_summary_renders_parallel_and_shortlists():
    worthiness = assess_parallel_worthiness(
        "先分析需求，再查资料，同时整理成计划",
        retrospective_count=1,
        skill_count=2,
    )
    context = RuntimeRequestContext(
        user_id="u1",
        session_id="c1",
        query_text="先分析需求，再查资料，同时整理成计划",
        recalled_memories=["最近偏好结构化输出"],
        retrospective_shortlist=[
            {
                "task_type": "analysis",
                "summary": "上次先检索再分析，结果更稳。",
            }
        ],
        shortlisted_skills=["weekly-planning"],
        skill_shortlist=[
            SkillShortlistEntry(
                skill_name="weekly-planning",
                score=0.82,
                rationale="命中计划关键词",
                injection_mode="summary",
            )
        ],
        parallel_worthiness=worthiness,
        recommended_runtime_mode="collaboration",
    )

    summary = render_runtime_request_context_summary(context)

    assert "Runtime Request Context" in summary
    assert "collaboration" in summary
    assert "weekly-planning" in summary


def test_build_session_retrospective_captures_skill_and_history_context():
    retrospective = build_session_retrospective(
        request_id="resp-1",
        session_id="conv-1",
        user_query="帮我分析并安排下周任务",
        state={
            "execution_mode": "collaboration",
            "current_agent": "analyst",
            "verification_status": "passed",
            "verification_summary": "ok",
            "final_response": "已经给出建议",
            "skill_shortlist": [{"skill_name": "weekly-planning"}],
            "event_trace": [{"event_type": "agent.execution.decided", "agent_id": "master"}],
            "verification_evidence": [{"type": "verification"}],
            "completed_tasks": [{"task_id": "t1", "title": "收集信息", "status": "completed"}],
            "retrospective_shortlist": [{"summary": "上次周计划拆解有效"}],
            "parallel_worthiness": {"score": 0.6},
        },
        runtime_context={
            "user_id": "u1",
            "recommended_runtime_mode": "collaboration",
        },
    )

    assert retrospective.user_id == "u1"
    assert retrospective.execution_mode == "collaboration"
    assert retrospective.used_skill_names == ["weekly-planning"]
    assert retrospective.context_snapshot["retrospective_shortlist_count"] == 1
    assert retrospective.outcome == "completed"


async def test_master_node_records_execution_decision_and_skill_shortlist_event():
    state = initial_state("u1", "c1")
    state["messages"] = [HumanMessage(content="帮我查一下资料并分析重点")]
    state["skill_shortlist"] = [
        {
            "skill_name": "research-synthesis",
            "score": 0.73,
            "injection_mode": "summary",
        }
    ]
    state["runtime_request_context"] = {
        "request_id": "req-1",
        "recommended_runtime_mode": "direct",
        "parallel_worthiness": {
            "preferred_mode": "direct",
            "score": 0.2,
            "estimated_subtasks": 1,
        },
    }
    state["task_graph"] = {
        "graph_id": "graph-1",
        "nodes": [{"node_id": "task-1", "title": "收集证据", "role": "librarian"}],
        "entry_node_ids": ["task-1"],
        "max_parallelism": 1,
    }

    result = await master_node(state)

    assert result["execution_decision"] is not None
    event_types = [item["event_type"] for item in result["event_trace"]]
    assert "agent.parallel.assessed" in event_types
    assert "agent.skill.shortlisted" in event_types
    assert "agent.task_graph.built" in event_types
    assert "agent.execution.decided" in event_types


async def test_master_node_records_rollback_event_when_parallel_task_graph_flag_is_disabled():
    async def fake_collaboration_flow(state, _user_query):
        state["execution_mode"] = "collaboration"
        state["final_response"] = "collaboration skipped in test"
        return state

    graph_module._run_collaboration_flow = fake_collaboration_flow
    state = initial_state("u1", "c1")
    state["messages"] = [HumanMessage(content="先查资料再分析风险再安排计划")]
    state["feature_flags"] = {"ENABLE_PARALLEL_TASK_GRAPH": False}
    state["parallel_worthiness"] = {
        "preferred_mode": "parallel",
        "score": 0.8,
        "estimated_subtasks": 3,
    }
    state["runtime_request_context"] = {
        "request_id": "req-2",
        "user_id": "u1",
        "session_id": "c1",
        "recommended_runtime_mode": "collaboration",
    }

    result = await master_node(state)

    event_types = [item["event_type"] for item in result["event_trace"]]
    assert "agent.rollback.triggered" in event_types


async def test_master_node_direct_mode_baseline_still_returns_simple_response():
    state = initial_state("u1", "c1")
    state["messages"] = [HumanMessage(content="你好")]

    result = await master_node(state)

    assert result["execution_mode"] == "direct"
    assert result["final_response"] is not None


async def test_master_node_collaboration_mode_baseline_still_respects_complex_request(monkeypatch):
    async def fake_collaboration_flow(state, _user_query):
        state["execution_mode"] = "collaboration"
        state["final_response"] = "collaboration baseline ok"
        return state

    graph_module._run_collaboration_flow = fake_collaboration_flow
    state = initial_state("u1", "c1")
    state["messages"] = [HumanMessage(content="先查资料，再分析风险，再安排计划")]

    result = await master_node(state)

    assert result["execution_mode"] == "collaboration"
    assert result["final_response"] == "collaboration baseline ok"
