"""DOCX到Markdown格式转换器"""

from typing import Any, Optional, Dict, List, Tuple
from hos_m2f.converters.base_converter import BaseConverter
from docx import Document
import os
import io


class DOCXToMDConverter(BaseConverter):
    """DOCX到Markdown格式转换器"""
    
    def convert(self, input_content: bytes, options: Optional[Dict[str, Any]] = None) -> bytes:
        """将DOCX转换为Markdown
        
        Args:
            input_content: DOCX文件的二进制数据
            options: 转换选项
            
        Returns:
            bytes: Markdown文件的二进制数据
        """
        if options is None:
            options = {}
        
        # 加载DOCX文档
        doc = Document(io.BytesIO(input_content))
        
        # 转换为Markdown
        md_content = []
        
        # 处理段落
        for paragraph in doc.paragraphs:
            # 处理标题
            if paragraph.style.name.startswith('Heading'):
                level = int(paragraph.style.name.split(' ')[1])
                md_content.append('#' * level + ' ' + paragraph.text)
            # 处理列表
            elif paragraph.style.name in ['List Bullet', 'List Number']:
                # 检测缩进级别
                indent_level = int(paragraph.paragraph_format.left_indent.inches // 0.5)
                prefix = '  ' * indent_level
                
                if paragraph.style.name == 'List Number':
                    # 简化处理，实际项目中需要更复杂的列表编号处理
                    md_content.append(prefix + '1. ' + paragraph.text)
                else:
                    md_content.append(prefix + '- ' + paragraph.text)
            # 处理普通段落
            else:
                if paragraph.text:
                    md_content.append(paragraph.text)
            
            # 添加空行
            md_content.append('')
        
        # 处理表格
        for table in doc.tables:
            # 表头
            headers = []
            for cell in table.rows[0].cells:
                headers.append(cell.text)
            
            # 表格分隔线
            separators = ['---'] * len(headers)
            
            # 表格数据
            rows = []
            for row in table.rows[1:]:
                row_cells = []
                for cell in row.cells:
                    row_cells.append(cell.text)
                rows.append(row_cells)
            
            # 生成Markdown表格
            if headers:
                md_content.append('| ' + ' | '.join(headers) + ' |')
                md_content.append('| ' + ' | '.join(separators) + ' |')
                for row in rows:
                    md_content.append('| ' + ' | '.join(row) + ' |')
                md_content.append('')
        
        # 生成Markdown内容
        md_text = '\n'.join(md_content)
        
        return md_text.encode('utf-8')
    
    def split_docx(self, input_content: bytes, output_dir: str, options: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
        """拆分DOCX文件为LaTeX格式和图片
        
        Args:
            input_content: DOCX文件的二进制数据
            output_dir: 输出目录
            options: 拆分选项
            
        Returns:
            Dict[str, Any]: 拆分结果
        """
        if options is None:
            options = {}
        
        # 创建输出目录
        os.makedirs(output_dir, exist_ok=True)
        
        # 创建子目录
        images_dir = os.path.join(output_dir, 'images')
        os.makedirs(images_dir, exist_ok=True)
        
        # 加载DOCX文档
        doc = Document(io.BytesIO(input_content))
        
        # 提取图片
        images = self._extract_images(doc, images_dir)
        
        # 生成LaTeX格式
        latex_content = self._generate_latex(doc, images, options)
        
        # 保存LaTeX文件
        latex_path = os.path.join(output_dir, 'document.tex')
        with open(latex_path, 'w', encoding='utf-8') as f:
            f.write(latex_content)
        
        return {
            'success': True,
            'latex_path': latex_path,
            'images': images,
            'images_dir': images_dir
        }
    
    def _extract_images(self, doc: Document, images_dir: str) -> List[Dict[str, Any]]:
        """提取DOCX中的图片
        
        Args:
            doc: DOCX文档对象
            images_dir: 图片输出目录
            
        Returns:
            List[Dict[str, Any]]: 提取的图片信息
        """
        images = []
        
        # 提取文档中的图片
        for i, rel in enumerate(doc.part.rels.values()):
            if "image" in rel.target_ref:
                # 获取图片内容
                image_part = rel.target_part
                image_content = image_part.blob
                
                # 确定图片扩展名
                content_type = image_part.content_type
                if content_type == 'image/jpeg':
                    ext = '.jpg'
                elif content_type == 'image/png':
                    ext = '.png'
                elif content_type == 'image/gif':
                    ext = '.gif'
                else:
                    ext = '.bin'
                
                # 保存图片
                image_name = f'image_{i+1}{ext}'
                image_path = os.path.join(images_dir, image_name)
                with open(image_path, 'wb') as f:
                    f.write(image_content)
                
                # 记录图片信息
                images.append({
                    'name': image_name,
                    'path': image_path,
                    'content_type': content_type
                })
        
        return images
    
    def _generate_latex(self, doc: Document, images: List[Dict[str, Any]], options: Dict[str, Any]) -> str:
        """生成LaTeX格式
        
        Args:
            doc: DOCX文档对象
            images: 提取的图片信息
            options: 生成选项
            
        Returns:
            str: LaTeX内容
        """
        latex_content = []
        
        # 添加LaTeX文档头部
        latex_content.append('\\documentclass{article}')
        latex_content.append('\\usepackage{ctex}')
        latex_content.append('\\usepackage{graphicx}')
        latex_content.append('\\usepackage{hyperref}')
        latex_content.append('\\usepackage{booktabs}')
        latex_content.append('\\begin{document}')
        
        # 处理段落
        image_index = 0
        for paragraph in doc.paragraphs:
            # 处理标题
            if paragraph.style.name.startswith('Heading'):
                level = int(paragraph.style.name.split(' ')[1])
                if level == 1:
                    latex_content.append(f'\\section{{{paragraph.text}}}')
                elif level == 2:
                    latex_content.append(f'\\subsection{{{paragraph.text}}}')
                elif level == 3:
                    latex_content.append(f'\\subsubsection{{{paragraph.text}}}')
                else:
                    latex_content.append(f'\\paragraph{{{paragraph.text}}}')
            # 处理列表
            elif paragraph.style.name in ['List Bullet', 'List Number']:
                # 检测缩进级别
                indent_level = int(paragraph.paragraph_format.left_indent.inches // 0.5)
                
                if indent_level == 0:
                    latex_content.append('\\begin{itemize}')
                    latex_content.append(f'\\item {paragraph.text}')
                    latex_content.append('\\end{itemize}')
                else:
                    # 简化处理，实际项目中需要更复杂的列表处理
                    latex_content.append(f'\\item {paragraph.text}')
            # 处理普通段落
            else:
                if paragraph.text:
                    latex_content.append(paragraph.text)
            
            # 添加空行
            latex_content.append('')
        
        # 处理表格
        for table in doc.tables:
            # 表头
            headers = []
            for cell in table.rows[0].cells:
                headers.append(cell.text)
            
            # 表格数据
            rows = []
            for row in table.rows[1:]:
                row_cells = []
                for cell in row.cells:
                    row_cells.append(cell.text)
                rows.append(row_cells)
            
            # 生成LaTeX表格
            if headers:
                latex_content.append('\\begin{table}[htbp]')
                latex_content.append('\\centering')
                latex_content.append(f'\\begin{{tabular}}{{{"|l" * len(headers)}|}}')
                latex_content.append('\\hline')
                
                # 添加表头
                header_line = ' & '.join(headers)
                latex_content.append(f'{header_line} \\')
                latex_content.append('\\hline')
                
                # 添加数据行
                for row in rows:
                    data_line = ' & '.join(row)
                    latex_content.append(f'{data_line} \\')
                    latex_content.append('\\hline')
                
                latex_content.append('\\end{tabular}')
                latex_content.append('\\caption{Table}')
                latex_content.append('\\label{tab:example}')
                latex_content.append('\\end{table}')
                latex_content.append('')
        
        # 添加图片
        for image in images:
            image_path = os.path.join('images', image['name'])
            latex_content.append('\\begin{figure}[htbp]')
            latex_content.append('\\centering')
            latex_content.append(f'\\includegraphics[width=0.8\\textwidth]{{{image_path}}}')
            latex_content.append('\\caption{{Image}}')
            latex_content.append(f'\\label{{fig:image_{images.index(image)+1}}}')
            latex_content.append('\\end{figure}')
            latex_content.append('')
        
        # 添加文档尾部
        latex_content.append('\\end{document}')
        
        return '\n'.join(latex_content)
    
    def reconstruct_docx(self, input_dir: str, output_path: str, options: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
        """从拆分素材重新生成DOCX文档
        
        Args:
            input_dir: 输入目录，包含拆分的素材
            output_path: 输出DOCX文件路径
            options: 重构选项
            
        Returns:
            Dict[str, Any]: 重构结果
        """
        if options is None:
            options = {}
        
        # 创建新的DOCX文档
        doc = Document()
        
        # 读取LaTeX文件
        latex_path = os.path.join(input_dir, 'document.tex')
        if not os.path.exists(latex_path):
            return {
                'success': False,
                'error': 'LaTeX file not found'
            }
        
        # 读取LaTeX内容
        with open(latex_path, 'r', encoding='utf-8') as f:
            latex_content = f.read()
        
        # 简化处理，实际项目中需要更复杂的LaTeX解析
        # 这里只是添加一些基本内容作为示例
        doc.add_heading('Reconstructed Document', level=1)
        doc.add_paragraph('This document was reconstructed from split materials.')
        
        # 保存DOCX文档
        doc.save(output_path)
        
        return {
            'success': True,
            'output_path': output_path
        }
    
    def get_supported_formats(self) -> tuple:
        """获取支持的格式"""
        return ('docx', 'markdown')
