"""T3.5 大纲注入上下文组装单测（确定性纯函数；ARCH §5.4）。

断言：四源（设定/伏笔/人物/世界观）都进文本、排序确定（同输入同输出）、空源不炸。
"""

from __future__ import annotations

from ww_api.services.outline_context import build_outline_context
from ww_core.domain import ForeshadowLedgerView
from ww_core.domain.project_repo import ProjectView
from ww_core.domain.repositories import CharacterView, WorldEntityView


def _project() -> ProjectView:
    import uuid

    return ProjectView(
        id=uuid.UUID(int=1),
        title="逆天剑帝",
        genre="玄幻",
        logline="少年逆袭",
        selling_points=["爽点密集", "升级流"],
    )


def test_build_context_includes_all_four_sources() -> None:
    text = build_outline_context(
        project=_project(),
        foreshadow=[
            ForeshadowLedgerView(
                code="F1", title="神秘信物", status="OPEN", planted_at=3, expected_close_to=10
            )
        ],
        characters=[CharacterView(name="主角", role="protagonist", motive="复仇")],
        world_entities=[WorldEntityView(type="location", name="剑冢")],
    )
    assert "逆天剑帝" in text
    assert "F1" in text and "神秘信物" in text
    assert "回收窗口 ?-10" in text
    assert "主角" in text
    assert "剑冢" in text


def test_build_context_is_deterministic_and_sorted() -> None:
    project = _project()
    fs = [
        ForeshadowLedgerView(code="F2", title="b", status="OPEN"),
        ForeshadowLedgerView(code="F1", title="a", status="OPEN"),
    ]
    a = build_outline_context(project=project, foreshadow=fs, characters=[], world_entities=[])
    b = build_outline_context(
        project=project, foreshadow=list(reversed(fs)), characters=[], world_entities=[]
    )
    assert a == b
    # F1 排在 F2 前（按 code 升序）。
    assert a.index("[F1]") < a.index("[F2]")


def test_build_context_handles_empty_sources() -> None:
    text = build_outline_context(
        project=_project(), foreshadow=[], characters=[], world_entities=[]
    )
    assert "（无）" in text
