"""文风学习 + 回炉端点的请求/响应 schema（C3 扩 / ARCH §7.2 / UX §6.9 / §8.3）。

snake_case（命名契约，见 memory/gotchas）。前端经 OpenAPI→TS 客户端消费——改字段
须 `pnpm gen:api` 重生成。
"""

from __future__ import annotations

import uuid
from typing import Annotated, Literal

from pydantic import BaseModel, Field, StringConstraints

# 请求文本长度上界（CR-H9：防超长入参空跑 LLM/DoS）。选段/样本 20k 字符，样本列表 ≤20 条。
_SEGMENT_MAX = 20_000
_SAMPLE_MAX = 20_000
_SAMPLES_LIST_MAX = 20
# 预检澄清沿用相同选段上界（DRY）；指令短。
_MAX_CLARIFY_SEGMENT_LEN = _SEGMENT_MAX
_MAX_CLARIFY_INSTRUCTION_LEN = 2000


class StyleLearnRequest(BaseModel):
    """学文风：上传样本正文（前端可读文件转文本）+ 模式（首学 / 更新）。"""

    # 同时约束**列表条数**与**每条样本长度**（最大 DoS 面：多条超长正文）。
    samples: list[Annotated[str, StringConstraints(max_length=_SAMPLE_MAX)]] = Field(
        min_length=1, max_length=_SAMPLES_LIST_MAX
    )
    mode: Literal["create", "update"] = "create"


class StyleLearnResponse(BaseModel):
    """学文风受理：返回 job_id（长任务，走 `GET /jobs/{id}` 轮询）。"""

    job_id: uuid.UUID


class DimensionEntry(BaseModel):
    """单个文风维度：名称 + 判定值 + 原文证据摘录（强类型，替代裸 dict[str, Any]）。"""

    name: str
    value: str
    evidence: list[str] = Field(default_factory=list)


class StyleFingerprintResponse(BaseModel):
    """最新文风指纹（`GET /style`）：完整 16 维（名称/值/证据）+ 版本（对齐 UX §6.9）。

    DB 存两列并行 dict（`{name:value}` + `{name:[evidence]}`）；响应合并为
    `list[DimensionEntry]`，给 TS 客户端强类型（替代弱类型 `dict[str, Any]`）。
    """

    dimensions: list[DimensionEntry] = Field(default_factory=list)
    version: int


class RefineRequest(BaseModel):
    """回炉：重写选中段（可选改写指令）。"""

    segment: str = Field(min_length=1, max_length=_SEGMENT_MAX)
    # CR-H9 收尾：再沟通意见喂 LLM，加上界（与 clarify instruction 同口径 2000）。
    instruction: str | None = Field(default=None, max_length=_MAX_CLARIFY_INSTRUCTION_LEN)


class RefineResponse(BaseModel):
    """回炉结果：原段 + 重写段（不写库，作者采纳经既有 draft 自动保存合入）。"""

    original: str
    refined: str


class RefineClarifyRequest(BaseModel):
    """润色预检澄清：选段 + 再沟通意见（WFW-9 M1 路线A 两阶段之「问题」阶段）。

    与 `RefineRequest` 独立——预检只判「意见清不清楚」，不改正文。`instruction` 为作者的
    再沟通意见（可空/极短，正是触发反问的场景）；带长度上界防超长入参。响应=`ClarifyDecision`
    （在 ww_agents，端点直接返回，供前端 gen:api 生成强类型客户端）。
    """

    segment: str = Field(min_length=1, max_length=_MAX_CLARIFY_SEGMENT_LEN)
    instruction: str = Field(default="", max_length=_MAX_CLARIFY_INSTRUCTION_LEN)
