# -*- coding: utf-8 -*-
# filename: document.py
# @Time    : 2025-01-20
# @Author  : Claude Code
# @Email   : noreply@anthropic.com
# @Software: PyCharm
"""Document file handler (Word/MD/TXT) for file preview tool"""
import logging
from pathlib import Path

from tf_tools_mcp.tools.file_preview_tools.file_preview_types import FilePreviewOptions
from tf_tools_mcp.tools.file_preview_tools.handlers.base import (
    BaseFileHandler,
    format_file_size,
)

logger = logging.getLogger(__name__)


class DocumentHandler(BaseFileHandler):
    """文档处理器 (Word/MD/TXT)"""

    supported_extensions = {".docx", ".doc", ".txt", ".md", ".markdown"}
    supported_mime_types = {
        "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
        "application/msword",
        "text/plain",
        "text/markdown",
    }

    async def extract_metadata(self, file_path: str) -> dict:
        """提取文档元数据

        Args:
            file_path: 文档文件路径

        Returns:
            文档元数据字典
        """
        path = Path(file_path)
        ext = path.suffix.lower()

        # 根据文件类型选择处理方式
        if ext in {".docx"}:
            return await self._extract_docx_metadata(file_path)
        elif ext in {".doc"}:
            # 旧版 .doc 暂不支持
            return {
                "char_count": 0,
                "preview_text": "旧版 .doc 格式暂不支持，请转换为 .docx 格式",
            }
        else:  # .txt, .md
            return await self._extract_text_metadata(file_path)

    async def _extract_docx_metadata(self, file_path: str) -> dict:
        """提取 DOCX 元数据"""
        try:
            from docx import Document

            doc = Document(file_path)

            # 提取所有段落文本
            all_text = []
            for para in doc.paragraphs:
                if para.text.strip():
                    all_text.append(para.text)

            full_text = "\n".join(all_text)

            # 截取预览文本（使用配置的 max_chars）
            max_chars = self.options.max_chars
            preview_text = full_text[:max_chars]
            if len(full_text) > max_chars:
                preview_text += "..."

            # 估算页数（DOCX无法准确获取页数，按2000字符/页估算）
            estimated_pages = max(
                1, (len(full_text) // 2000) + (1 if len(full_text) % 2000 > 0 else 0)
            )

            return {
                "char_count": len(full_text),
                "estimated_pages": estimated_pages,
                "preview_text": preview_text,
            }
        except Exception as e:
            logger.error(f"Failed to extract DOCX metadata: {e}")
            return {
                "char_count": 0,
                "estimated_pages": 0,
                "preview_text": f"文档解析失败: {str(e)}",
            }

    async def _extract_text_metadata(self, file_path: str) -> dict:
        """提取纯文本元数据"""
        try:
            # 尝试不同编码
            encodings = ["utf-8", "gbk", "gb2312", "latin-1"]
            content = None

            for encoding in encodings:
                try:
                    with open(file_path, "r", encoding=encoding) as f:
                        content = f.read()
                    break
                except UnicodeDecodeError:
                    continue

            if content is None:
                raise ValueError("无法解码文件内容")

            # 截取预览文本（使用配置的 max_chars）
            max_chars = self.options.max_chars
            preview_text = content[:max_chars]
            if len(content) > max_chars:
                preview_text += "..."

            # 估算页数（按2000字符/页估算）
            estimated_pages = max(
                1, (len(content) // 2000) + (1 if len(content) % 2000 > 0 else 0)
            )

            return {
                "char_count": len(content),
                "estimated_pages": estimated_pages,
                "preview_text": preview_text,
            }
        except Exception as e:
            logger.error(f"Failed to extract text metadata: {e}")
            return {
                "char_count": 0,
                "estimated_pages": 0,
                "preview_text": f"文本读取失败: {str(e)}",
            }

    async def generate_summary(self, file_path: str) -> str | None:
        """文档格式生成内容摘要

        Args:
            file_path: 文档文件路径

        Returns:
            格式化的内容摘要
        """
        # 获取元数据
        metadata = await self.get_file_metadata(file_path)
        format_metadata = await self.extract_metadata(file_path)

        # 构建摘要
        lines = [
            f"文件名：{metadata.filename}",
            f"大小：{format_file_size(metadata.file_size)}",
            f"类型：{metadata.file_type}",
        ]

        # 添加页数信息
        if format_metadata.get("estimated_pages"):
            lines.append(f"页数：约{format_metadata['estimated_pages']}页")

        if format_metadata.get("char_count") is not None:
            lines.append(f"字符数：{format_metadata['char_count']}")

        # 添加内容预览
        preview = format_metadata.get("preview_text", "")
        if preview:
            lines.append(f"\n内容预览：\n{preview}")

        return "\n".join(lines)
