"""Pydantic models for the Notebook API.

Notebook 模块的请求/响应数据模型。
"""

from __future__ import annotations

from datetime import datetime
from typing import Any

from pydantic import BaseModel, Field, model_validator


# ---------------------------------------------------------------------------
# Notebook config
# ---------------------------------------------------------------------------

class NotebookConfig(BaseModel):
    """Notebook 对话配置。"""
    goal: str = Field(default="", description="对话目标，引导 AI 关注方向")
    style: str = Field(default="", description="风格/角色描述，如'政策分析师'")
    answer_length: str = Field(default="medium", pattern="^(short|medium|long)$", description="回答长度: short / medium / long")


# ---------------------------------------------------------------------------
# Notebook CRUD
# ---------------------------------------------------------------------------

class NotebookCreateRequest(BaseModel):
    title: str = Field(default="未命名 Notebook", max_length=500)
    description: str = Field(default="", max_length=2000)


class NotebookUpdateRequest(BaseModel):
    title: str | None = Field(None, max_length=500)
    description: str | None = Field(None, max_length=2000)
    config: NotebookConfig | None = None


class NotebookSummary(BaseModel):
    id: str
    title: str
    description: str | None = None
    status: str
    source_count: int = 0
    message_count: int = 0
    created_at: datetime | None = None
    updated_at: datetime | None = None


class NotebookDetail(BaseModel):
    id: str
    title: str
    description: str | None = None
    status: str
    config: NotebookConfig | None = None
    sources: list[NotebookSourceInfo] = []
    created_at: datetime | None = None
    updated_at: datetime | None = None


# ---------------------------------------------------------------------------
# Sources
# ---------------------------------------------------------------------------

class AddSourceBySearchRequest(BaseModel):
    doc_id: str = Field(..., description="已有文档的 doc_id")
    title: str = Field(default="", max_length=500, description="文档标题")


class AddSourceByPasteRequest(BaseModel):
    title: str = Field(..., min_length=1, max_length=500, description="来源标题")
    content: str = Field(..., min_length=1, max_length=200000, description="粘贴文本内容")


class SourceUpdateRequest(BaseModel):
    selected: bool | None = None
    title: str | None = Field(None, max_length=500)


class NotebookSourceInfo(BaseModel):
    model_config = {"extra": "ignore"}

    id: str
    notebook_id: str
    source_type: str
    title: str
    doc_id: str | None = None
    ingest_status: str
    ingest_error: str | None = None
    ingest_task_id: str | None = None
    summary: str | None = None
    selected: bool = True
    sort_order: int = 0
    created_at: datetime | None = None
    updated_at: datetime | None = None


# ---------------------------------------------------------------------------
# Chat
# ---------------------------------------------------------------------------

class NotebookChatRequest(BaseModel):
    question: str = Field(..., min_length=1, max_length=4000, description="用户问题")
    session_id: str = Field(default="default", description="对话会话 ID")


class NotebookChatConfigRequest(BaseModel):
    config: NotebookConfig


class NotebookChatMessage(BaseModel):
    id: str
    role: str
    content: str | None = None
    references: list[dict[str, Any]] | None = None
    suggestions: list[str] | None = None
    created_at: datetime | None = None


class NotebookChatHistoryResponse(BaseModel):
    notebook_id: str
    session_id: str
    messages: list[NotebookChatMessage]
    total: int = 0


class SuggestionsResponse(BaseModel):
    suggestions: list[str]


# ---------------------------------------------------------------------------
# Outputs
# ---------------------------------------------------------------------------

_VALID_OUTPUT_TYPES = {
    "briefing", "study_guide", "blog_post", "science_handbook",
    "implementation_plan", "speech_draft", "policy_brief", "summary_report", "custom",
}


class OutputGenerateRequest(BaseModel):
    output_type: str = Field(..., description="输出类型")
    title: str = Field(default="", max_length=500, description="输出文档标题（可选）")
    custom_instructions: str = Field(default="", max_length=4000, description="自定义指令")

    @model_validator(mode="after")
    def _validate_output_type(self):
        if self.output_type not in _VALID_OUTPUT_TYPES:
            raise ValueError(f"不支持的输出类型: {self.output_type}，可选: {', '.join(sorted(_VALID_OUTPUT_TYPES))}")
        return self


class NotebookOutputInfo(BaseModel):
    id: str
    notebook_id: str
    output_type: str
    title: str
    status: str
    error: str | None = None
    created_at: datetime | None = None
    updated_at: datetime | None = None


class NotebookOutputDetail(BaseModel):
    id: str
    notebook_id: str
    output_type: str
    title: str
    content_md: str | None = None
    status: str
    error: str | None = None
    created_at: datetime | None = None
    updated_at: datetime | None = None


# ---------------------------------------------------------------------------
# List response wrappers
# ---------------------------------------------------------------------------

class NotebookListResponse(BaseModel):
    items: list[NotebookSummary]
    total: int


class SourceListResponse(BaseModel):
    items: list[NotebookSourceInfo]
    total: int
    max_sources: int = 10


class OutputListResponse(BaseModel):
    items: list[NotebookOutputInfo]
    total: int


# Fix forward reference
NotebookDetail.model_rebuild()
