"""T6.3 创作工具箱 context 派发纯函数单测（LLM-free，确定性）。

每种策略的注入文本形状 + with_outline_chapter 缺节拍降级（空 beats 不报错）。
"""

from __future__ import annotations

import pytest
from ww_api.services.toolbox_context import build_toolbox_context


def test_brief_only_includes_setting_and_brief() -> None:
    text = build_toolbox_context(
        "brief_only", brief="爽文脑洞", project_context="标题：测试\n题材：玄幻"
    )
    assert "## 作品设定" in text
    assert "标题：测试" in text
    assert "## 创作需求" in text
    assert "爽文脑洞" in text


def test_brief_only_empty_brief_degrades() -> None:
    text = build_toolbox_context("brief_only", brief="", project_context="标题：测试")
    # 空 brief → 降级占位（由 system_prompt 的「自由发散」纪律处理）。
    assert "自由发散" in text


def test_with_project_uses_brief_context() -> None:
    text = build_toolbox_context(
        "with_project", brief="多版简介", project_context="标题：测试\n前提：废柴逆袭"
    )
    assert "前提：废柴逆袭" in text
    assert "多版简介" in text


def test_with_world_injects_world_block() -> None:
    text = build_toolbox_context(
        "with_world",
        brief="取个名字",
        project_context="标题：测试",
        world_context="- [力量体系] 灵脉：灵力守恒",
    )
    assert "## 世界观" in text
    assert "灵脉" in text
    assert "取个名字" in text


def test_with_world_empty_world_degrades() -> None:
    text = build_toolbox_context(
        "with_world", brief="x", project_context="标题：测试", world_context=""
    )
    assert "暂无世界观设定" in text


def test_with_outline_chapter_injects_beats() -> None:
    text = build_toolbox_context(
        "with_outline_chapter",
        brief="展开细纲",
        project_context="标题：测试",
        chapter_no=3,
        beats=["主角觉醒", "初遇反派"],
    )
    assert "第 3 章大纲节拍" in text
    assert "主角觉醒" in text
    assert "初遇反派" in text
    assert "展开细纲" in text


def test_with_outline_chapter_missing_beats_does_not_error() -> None:
    # 缺章/缺大纲 → 空节拍占位，不报错（预览降级）。
    text = build_toolbox_context(
        "with_outline_chapter",
        brief="",
        project_context="标题：测试",
        chapter_no=99,
        beats=[],
    )
    assert "第 99 章大纲节拍" in text
    assert "暂无大纲节拍" in text


def test_with_prior_chapter_injects_prior_text_and_beats() -> None:
    text = build_toolbox_context(
        "with_prior_chapter",
        brief="续写下文",
        project_context="标题：测试",
        prior_text="他推开门，看见了那道身影。",
        beats=["主角揭穿阴谋"],
    )
    assert "前文正文" in text
    assert "他推开门" in text
    assert "主角揭穿阴谋" in text


def test_with_prior_chapter_empty_prior_degrades() -> None:
    text = build_toolbox_context(
        "with_prior_chapter", brief="", project_context="标题：测试", prior_text=""
    )
    # 无前文 → 降级占位（不报错），交由 system_prompt 处理。
    assert "暂无前文" in text


def test_text_input_injects_source_text() -> None:
    text = build_toolbox_context(
        "text_input",
        brief="加强环境描写",
        project_context="标题：测试",
        text="原始的一段正文。",
    )
    assert "## 原文" in text
    assert "原始的一段正文" in text
    assert "加强环境描写" in text


def test_text_input_empty_text_degrades() -> None:
    text = build_toolbox_context("text_input", brief="", project_context="标题：测试", text="")
    assert "未提供原文" in text


def test_unknown_strategy_raises() -> None:
    with pytest.raises(ValueError):
        build_toolbox_context("nope", brief="x", project_context="y")  # type: ignore[arg-type]
