# -*- coding: utf-8 -*-
# filename: ppt.py
# @Time    : 2025-01-20
# @Author  : Claude Code
# @Email   : noreply@anthropic.com
# @Software: PyCharm
"""PPT file handler for file preview tool"""
import logging
from pathlib import Path

from pptx import Presentation

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

logger = logging.getLogger(__name__)


class PPTHandler(BaseFileHandler):
    """PPT 处理器"""

    supported_extensions = {".pptx", ".ppt"}
    supported_mime_types = {
        "application/vnd.openxmlformats-officedocument.presentationml.presentation",
        "application/vnd.ms-powerpoint",
    }

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

        Args:
            file_path: PPT 文件路径

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

        # 旧版 .ppt 暂不支持
        if ext == ".ppt":
            return {
                "slide_count": 0,
                "preview_slides": [],
            }

        # 读取 .pptx 文件
        prs = Presentation(file_path)
        slide_count = len(prs.slides)

        # 提取前 N 页信息
        max_slides = min(self.options.max_preview_slides, slide_count)
        preview_slides = []

        for i in range(max_slides):
            slide = prs.slides[i]
            slide_number = i + 1

            # 提取文本内容
            text_content = self._extract_text_from_slide(slide)

            # 创建 SlideInfo
            slide_info = SlideInfo(
                slide_number=slide_number,
                image=None,  # 不在元数据中生成截图（需要时在 generate_summary 中生成）
                text_content=text_content,
            )

            preview_slides.append(slide_info.model_dump())

        return {
            "slide_count": slide_count,
            "preview_slides": preview_slides,
        }

    def _extract_text_from_slide(self, slide) -> str:
        """从幻灯片提取文本内容"""
        text_parts = []

        # 遍历所有形状
        for shape in slide.shapes:
            if hasattr(shape, "text") and shape.text:
                text_parts.append(shape.text)

            # 处理表格
            if shape.has_table:
                table = shape.table
                for row in table.rows:
                    row_text = []
                    for cell in row.cells:
                        if cell.text:
                            row_text.append(cell.text)
                    if row_text:
                        text_parts.append(" | ".join(row_text))

            # 处理组合形状（如果支持）
            if shape.shape_type == 14 and hasattr(shape, "shapes"):  # Group shape
                for sub_shape in shape.shapes:
                    if hasattr(sub_shape, "text") and sub_shape.text:
                        text_parts.append(sub_shape.text)

        return "\n".join(text_parts)

    async def generate_summary(self, file_path: str) -> str | None:
        """生成 PPT 内容描述（强制提取文字+LLM）

        Args:
            file_path: PPT 文件路径

        Returns:
            AI生成的PPT分析内容（不包含文件基本信息）
        """
        path = Path(file_path)

        # 旧版 .ppt 暂不支持
        if path.suffix.lower() == ".ppt":
            return "注意：旧版 .ppt 格式暂不支持内容描述生成。"

        try:
            # 读取 PPT
            prs = Presentation(file_path)

            # 提取所有幻灯片的文本
            slide_texts = []
            for i, slide in enumerate(prs.slides):
                text = self._extract_text_from_slide(slide)
                if text.strip():
                    slide_texts.append(f"=== 幻灯片 {i + 1} ===\n{text}")

            # 组合文本内容，最多2000字符
            full_text = "\n\n".join(slide_texts)
            if len(full_text) > 2000:
                full_text = full_text[:2000] + "\n... (内容已截断)"

            # 调用文本生成函数获取梗概
            summary_text = await self._generate_text_summary(full_text)

            # 只返回AI生成的描述内容
            return summary_text[:1000]

        except Exception as e:
            logger.error(f"Failed to generate PPT summary: {e}")
            # 出错时返回错误提示
            return "注意：内容描述生成失败。"

    async def _generate_text_summary(self, text: str) -> str:
        """使用LLM生成文本摘要

        Args:
            text: 输入文本

        Returns:
            摘要文本
        """
        try:
            import zhipuai
            import os

            api_key = os.environ.get("ZHIPUAI_API_KEY")
            if not api_key:
                logger.warning("ZHIPUAI_API_KEY not found, returning original text")
                return text[:1000]

            client = zhipuai.ZhipuAI(api_key=api_key)

            response = client.chat.completions.create(
                model="glm-4-flash",
                messages=[
                    {
                        "role": "user",
                        "content": f"请为以下PPT内容生成一个简洁的内容摘要（不超过1000字）：\n\n{text}",
                    }
                ],
                max_tokens=600,
            )

            return response.choices[0].message.content or text[:1000]

        except Exception as e:
            logger.error(f"Failed to generate text summary: {e}")
            return text[:1000]
