from __future__ import annotations

from datetime import datetime
from typing import Any

from pydantic import BaseModel, ConfigDict, Field


class KnowledgeFolderRead(BaseModel):
    name: str
    count: int
    icon: str = "mdi mdi-folder"


class KnowledgePreviewStatRead(BaseModel):
    label: str
    value: str


class KnowledgePreviewBlockRead(BaseModel):
    heading: str
    lines: list[str] = Field(default_factory=list)


class KnowledgePreviewPageRead(BaseModel):
    title: str
    subtitle: str
    stats: list[KnowledgePreviewStatRead] = Field(default_factory=list)
    blocks: list[KnowledgePreviewBlockRead] = Field(default_factory=list)


class KnowledgeDocumentRead(BaseModel):
    id: str
    scope: str = "tenant"
    readOnly: bool = False
    name: str
    folder: str
    tag: str
    time: str
    ingestTime: str = ""
    version: str
    stateCode: int = 1
    state: str
    stateTone: str
    owner: str
    icon: str
    fileType: str
    fileTypeLabel: str
    summary: str
    mimeType: str
    extension: str
    sizeBytes: int
    canPreview: bool = False
    llmWikiAvailable: bool = False
    llmWikiQualityStatus: str = ""
    llmWikiQualityNote: str = ""


class KnowledgeDocumentDetailRead(KnowledgeDocumentRead):
    previewKind: str
    previewPages: list[KnowledgePreviewPageRead] = Field(default_factory=list)


class KnowledgeOnlyOfficeConfigRead(BaseModel):
    documentServerUrl: str
    config: dict[str, Any] = Field(default_factory=dict)


class KnowledgeOnlyOfficeCallbackRead(BaseModel):
    error: int = 0


class KnowledgeOnlyOfficeCallbackWrite(BaseModel):
    model_config = ConfigDict(extra="allow")

    status: int = Field(description="ONLYOFFICE 回调状态码。")
    url: str | None = Field(default=None, description="文档下载地址，状态为 2 或 6 时使用。")
    users: list[str] = Field(default_factory=list, description="当前编辑用户列表。")


class KnowledgeLibraryRead(BaseModel):
    folders: list[KnowledgeFolderRead] = Field(default_factory=list)
    documents: list[KnowledgeDocumentRead] = Field(default_factory=list)


class KnowledgeActionResponse(BaseModel):
    ok: bool = True
    detail: str


class LlmWikiChunkRead(BaseModel):
    chunk_id: str
    title: str
    content: str
    source_page: int | None = None
    word_count: int = 0
    tags: list[str] = Field(default_factory=list)


class LlmWikiKnowledgeCandidateRead(BaseModel):
    candidate_id: str
    title: str
    content: str
    domain: str = "expense"
    scenario: str = "reimbursement_policy"
    tags: list[str] = Field(default_factory=list)
    source_document_id: str
    source_document_name: str
    source_chunk_ids: list[str] = Field(default_factory=list)
    evidence: list[str] = Field(default_factory=list)
    confidence: float = 0.0
    status: str = "draft"
    created_by: str = "hermes"
    created_at: datetime | None = None
    extraction_mode: str = "hermes"
    quality_flags: list[str] = Field(default_factory=list)
    fallback_reason: str = ""


class LlmWikiRuleCandidateRead(BaseModel):
    candidate_id: str
    source_type: str = "policy_document"
    template_key: str
    template_label: str
    domain: str = "expense"
    scenario: str = "reimbursement_policy"
    suggested_rule_name: str
    summary: str = ""
    template_sections: dict[str, Any] = Field(default_factory=dict)
    rule_markdown_draft: str
    runtime_rule: dict[str, Any] = Field(default_factory=dict)
    evidence: list[str] = Field(default_factory=list)
    confidence: float = 0.0
    source_document_id: str
    source_document_name: str
    source_chunk_ids: list[str] = Field(default_factory=list)
    generated_asset_id: str | None = None
    generated_asset_code: str | None = None
    generated_version: str | None = None
    validation_status: str = "valid"
    validation_errors: list[str] = Field(default_factory=list)
    status: str = "draft"
    created_by: str = "hermes"
    created_at: datetime | None = None


class LlmWikiDocumentRead(BaseModel):
    document_id: str
    document_name: str
    folder: str
    document_version: str = "v1.0"
    checksum: str = ""
    extracted_text_path: str
    chunk_count: int = 0
    candidate_chunk_count: int = 0
    filtered_chunk_count: int = 0
    group_count: int = 0
    successful_group_count: int = 0
    failed_group_count: int = 0
    knowledge_candidate_count: int = 0
    formal_knowledge_candidate_count: int = 0
    fallback_knowledge_candidate_count: int = 0
    rule_candidate_count: int = 0
    quality_status: str = "formal"
    quality_note: str = ""
    updated_at: datetime | None = None


class LlmWikiDocumentDetailRead(LlmWikiDocumentRead):
    knowledge_summary_markdown: str = ""
    chunks: list[LlmWikiChunkRead] = Field(default_factory=list)
    knowledge_candidates: list[LlmWikiKnowledgeCandidateRead] = Field(default_factory=list)
    rule_candidates: list[LlmWikiRuleCandidateRead] = Field(default_factory=list)


class LlmWikiIndexRead(BaseModel):
    documents: list[LlmWikiDocumentRead] = Field(default_factory=list)
    sync_run_count: int = 0


class LlmWikiSyncWrite(BaseModel):
    folder: str = Field(default="报销制度", min_length=1)
    document_ids: list[str] = Field(default_factory=list)
    force: bool = False


class LlmWikiSyncRead(BaseModel):
    ok: bool = True
    run_id: str
    folder: str
    document_count: int = 0
    knowledge_candidate_count: int = 0
    rule_candidate_count: int = 0
    generated_rule_count: int = 0
    generated_rule_asset_ids: list[str] = Field(default_factory=list)
    summary: str = ""


class LlmWikiSyncTaskRead(BaseModel):
    ok: bool = True
    agent_run_id: str
    folder: str
    document_ids: list[str] = Field(default_factory=list)
    queued_at: datetime
    status: str = "running"
    summary: str = ""


class LlmWikiSummaryUpdateWrite(BaseModel):
    knowledge_summary_markdown: str = Field(min_length=1)
