"""WFW-9 M1 clarify 节点单测：build_clarify_request + run_clarify（路线A 两阶段）。

注入 mock 网关（产 `ClarifyDecision` parsed），无真 LLM、无真 Postgres。clarify 是独立
非流式预检（不在写章/审稿流水线），裸函数；只判不改、**不写库**（不变量 #3）。asyncio_mode=auto。
"""

from __future__ import annotations

import uuid

from fakes_orchestrator import FakeRunGateway
from ww_agents import (
    ClarifyDecision,
    ClarifyOption,
    ClarifyQuestion,
    WorldGenResult,
    clarify_refine_spec,
)
from ww_core.orchestrator import build_clarify_request, run_clarify

PROJECT = uuid.UUID("00000000-0000-0000-0000-000000000001")
USER = uuid.UUID("00000000-0000-0000-0000-0000000000aa")

_NEED = ClarifyDecision(
    need_clarification=True,
    questions=[
        ClarifyQuestion(
            question="你想让这段更有张力，是指哪种方向？",
            options=[
                ClarifyOption(label="加快节奏", value="拆短句、压缩铺陈"),
                ClarifyOption(label="加重冲突", value="强化人物对立"),
            ],
            allow_free_text=True,
        )
    ],
)

_CLEAR = ClarifyDecision(
    need_clarification=False,
    verification="我会把被字句改成主动句，其余不动，对吗？",
)


# ---- build_clarify_request：analyst 档 + 结构化 + 缓存前缀无易变 ----


def test_build_clarify_request_declares_analyst_tier_and_schema() -> None:
    req = build_clarify_request(
        clarify_refine_spec,
        context="## 待重写段落\n原段。\n\n## 改写指令\n再改改",
        user_id=USER,
        project_id=PROJECT,
    )
    # 不变量 #2：只声明 analyst 档，不传 model。
    assert req.tier == "analyst"
    # 结构化预检：非流式 + 带 ClarifyDecision output_schema。
    assert req.stream is False
    assert req.output_schema is ClarifyDecision
    # 注入材料进 input（断点后）。
    assert "再改改" in req.input


def test_build_clarify_request_system_prefix_is_doctrine_only_cacheable() -> None:
    # 不变量 #9：system 前缀只放教条、cache=True，无历史/时间戳/UUID（可缓存）。
    req = build_clarify_request(
        clarify_refine_spec, context="ctx", user_id=USER, project_id=PROJECT
    )
    assert len(req.system) == 1
    block = req.system[0]
    assert block.cache is True
    assert block.text == clarify_refine_spec.system_prompt
    # 易变值绝不进缓存前缀。
    assert str(PROJECT) not in block.text
    assert "ctx" not in block.text


# ---- run_clarify：正常返回 + 校验失败确定性回退 ----


async def test_run_clarify_returns_need_clarification_decision() -> None:
    gateway = FakeRunGateway(_NEED)

    result = await run_clarify(
        clarify_refine_spec,
        context="## 待重写段落\n原段。",
        gateway=gateway,
        user_id=USER,
        project_id=PROJECT,
    )

    assert isinstance(result, ClarifyDecision)
    assert result.need_clarification is True
    assert len(result.questions) == 1
    assert result.questions[0].options[0].label == "加快节奏"
    assert gateway.call_count == 1


async def test_run_clarify_returns_clear_decision() -> None:
    gateway = FakeRunGateway(_CLEAR)

    result = await run_clarify(
        clarify_refine_spec,
        context="ctx",
        gateway=gateway,
        user_id=USER,
        project_id=PROJECT,
    )

    assert result.need_clarification is False
    assert result.verification is not None


async def test_run_clarify_falls_back_to_no_clarification_on_wrong_parsed() -> None:
    # 判别/校验失败：网关返回非 ClarifyDecision（畸形/降级）→ 确定性回退不问、放行。
    gateway = FakeRunGateway(WorldGenResult(entities=[]))

    result = await run_clarify(
        clarify_refine_spec,
        context="ctx",
        gateway=gateway,
        user_id=USER,
        project_id=PROJECT,
    )

    assert isinstance(result, ClarifyDecision)
    assert result.need_clarification is False
    assert result.questions == []
