from io import BytesIO
from pathlib import Path

from pypdf import PdfReader

from zbt.core.errors import AppError

MAX_DOCUMENT_BYTES = 10 * 1024 * 1024


def extract_document_text(file_name: str, payload: bytes) -> str:
    if len(payload) > MAX_DOCUMENT_BYTES:
        raise AppError("KNOWLEDGE_FILE_TOO_LARGE", "知识文档不能超过10MB", 413)
    suffix = Path(file_name).suffix.lower()
    if suffix in {".txt", ".md"}:
        try:
            content = payload.decode("utf-8-sig")
        except UnicodeDecodeError as error:
            raise AppError(
                "KNOWLEDGE_FILE_ENCODING_INVALID",
                "文本知识文档必须使用UTF-8编码",
                422,
            ) from error
    elif suffix == ".pdf":
        try:
            reader = PdfReader(BytesIO(payload))
            content = "\n\n".join((page.extract_text() or "").strip() for page in reader.pages)
        except Exception as error:
            raise AppError("KNOWLEDGE_PDF_INVALID", "PDF文件无法解析", 422) from error
    else:
        raise AppError(
            "KNOWLEDGE_FILE_TYPE_UNSUPPORTED",
            "知识库目前只支持TXT、Markdown和PDF文件",
            415,
        )
    normalized = content.strip()
    if len(normalized) < 10:
        raise AppError(
            "KNOWLEDGE_FILE_CONTENT_EMPTY",
            "文档没有提取到足够的有效文字",
            422,
        )
    return normalized

