"""创作工具箱 · context 派发（PURE，LLM-free，确定性）。

把 `ContextStrategy` 映射成喂给网关的注入文本。**纯函数**：给定已组装好的材料
（项目设定 / 世界观文本 / 本章节拍），同输入同输出、无 IO、无时间戳——便于单测与缓存。

IO（读 projects/world_entities/outline）发生在端点；本模块只负责「材料 → 注入文本」的
确定性拼装，复用 `ww_core.orchestrator` 的既有 context builders（brief / outline-chapter）
与 `routers/generation` 的 `_project_context` / `_world_context` 序列化口径。

策略 → 材料：
- `brief_only`         ：作品设定（仅标题/题材级）+ 一句话需求；
- `with_project`       ：作品设定（含前提/主题）+ 一句话需求；
- `with_world`         ：作品设定 + world_entities 硬规则卡 + 一句话需求；
- `with_outline_chapter`：作品设定 + 指定章大纲节拍（缺章/缺大纲 → 空节拍，不报错）；
- `with_prior_chapter`  ：作品设定 + 最新已写正文（端点先读 accepted/draft）+ 可选节拍；
- `text_input`          ：作品设定 + 作者提供的原文（扩写/降AI/拆书样本）+ 一句话需求。
"""

from __future__ import annotations

from collections.abc import Sequence

from ww_core.orchestrator import (
    build_brief_context,
    build_continuation_context,
    build_outline_chapter_context,
    build_text_input_context,
)
from ww_skills import ContextStrategy


def build_toolbox_context(
    strategy: ContextStrategy,
    *,
    brief: str,
    project_context: str,
    world_context: str = "",
    chapter_no: int | None = None,
    beats: Sequence[str] = (),
    prior_text: str = "",
    text: str = "",
) -> str:
    """据注入策略组装喂网关的文本（PURE，确定性）。

    `project_context` 由调用方按策略序列化（brief_only 给精简设定、with_project 给完整设定）；
    `world_context` 仅 with_world 用（已序列化的硬规则卡）；`chapter_no`/`beats` 仅
    with_outline_chapter 用（缺章/缺大纲时 beats 为空，降级到空节拍而非报错）；
    `prior_text` 仅 with_prior_chapter 用（端点先读最新 accepted/draft 正文注入）；
    `text` 仅 text_input 用（作者提供的原文样本）。
    """
    if strategy in ("brief_only", "with_project"):
        return build_brief_context(brief=brief, project_context=project_context)

    if strategy == "with_prior_chapter":
        return build_continuation_context(
            project_context=project_context,
            prior_text=prior_text,
            beats=list(beats) if beats else None,
        )

    if strategy == "text_input":
        return build_text_input_context(project_context=project_context, text=text, brief=brief)

    if strategy == "with_world":
        base = build_brief_context(brief=brief, project_context=project_context)
        world_block = world_context.strip() or "（暂无世界观设定）"
        return f"{base}\n\n## 世界观（硬规则供契合/校验）\n{world_block}"

    if strategy == "with_outline_chapter":
        # 缺章号时退回首章占位（端点对需要章号的工具会先校验，这里只做确定性兜底）。
        no = chapter_no if chapter_no is not None else 1
        outline_block = build_outline_chapter_context(
            chapter_no=no, beats=beats, project_context=project_context
        )
        brief_block = brief.strip()
        if brief_block:
            return f"{outline_block}\n\n## 创作需求\n{brief_block}"
        return outline_block

    # 受限枚举不应到达此分支；保守抛错而非静默错配策略。
    raise ValueError(f"unknown context strategy: {strategy!r}")
