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

from typing import Any, Optional, Dict
from docx import Document
from docx.shared import Inches, Pt
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.style import WD_STYLE_TYPE
from hos_m2f.converters.base_converter import BaseConverter
import mistune


class MDToDOCXConverter(BaseConverter):
    """Markdown到DOCX格式转换器"""
    
    def convert(self, input_content: str, options: Optional[Dict[str, Any]] = None) -> bytes:
        """将Markdown转换为DOCX
        
        Args:
            input_content: Markdown内容
            options: 转换选项
            
        Returns:
            bytes: DOCX文件的二进制数据
        """
        if options is None:
            options = {}
        
        # 创建文档
        doc = Document()
        
        # 设置默认样式
        self._setup_styles(doc)
        
        # 解析Markdown
        markdown = mistune.create_markdown(
            plugins=[
                'url',
                'abbr',
                'def_list',
                'footnotes',
                'tables',
                'task_lists',
                'strikethrough',
                'highlight',
                'superscript',
                'subscript'
            ]
        )
        
        # 自定义渲染器
        class DOCXRenderer(mistune.HTMLRenderer):
            def __init__(self, doc):
                super().__init__()
                self.doc = doc
                self.current_paragraph = None
                self.list_level = 0
                self.lists = []
            
            def paragraph(self, text):
                if text.strip():
                    p = self.doc.add_paragraph()
                    p.add_run(text)
                return ''
            
            def heading(self, text, level):
                if level == 1:
                    self.doc.add_heading(text, level=0)
                else:
                    self.doc.add_heading(text, level=level-1)
                return ''
            
            def list(self, text, ordered, level, start=None):
                self.list_level += 1
                self.lists.append(ordered)
                return ''
            
            def list_item(self, text, level):
                if text.strip():
                    p = self.doc.add_paragraph(
                        text,
                        style='List Number' if self.lists[level-1] else 'List Bullet'
                    )
                    # 缩进
                    for i in range(level-1):
                        p.paragraph_format.left_indent += Inches(0.5)
                return ''
            
            def list_end(self, level):
                self.list_level -= 1
                if self.lists:
                    self.lists.pop()
                return ''
            
            def table(self, text):
                # 简化处理，实际项目中需要更复杂的表格解析
                self.doc.add_paragraph('Table: ' + text[:100] + '...')
                return ''
            
            def image(self, src, alt='', title=None):
                try:
                    # 简化处理，实际项目中需要处理本地和远程图片
                    self.doc.add_paragraph(f'Image: {alt} ({src})')
                except Exception:
                    pass
                return ''
            
            def link(self, link, text=None, title=None):
                if text:
                    p = self.doc.add_paragraph()
                    run = p.add_run(text)
                    # 实际项目中需要添加超链接
                return ''
            
            def emphasis(self, text):
                if self.current_paragraph:
                    run = self.current_paragraph.add_run(text)
                    run.italic = True
                return ''
            
            def strong(self, text):
                if self.current_paragraph:
                    run = self.current_paragraph.add_run(text)
                    run.bold = True
                return ''
            
            def codespan(self, text):
                p = self.doc.add_paragraph()
                run = p.add_run(text)
                run.font.name = 'Courier New'
                return ''
            
            def block_code(self, code, lang=None):
                p = self.doc.add_paragraph()
                run = p.add_run(code)
                run.font.name = 'Courier New'
                p.paragraph_format.left_indent = Inches(0.5)
                return ''
        
        # 渲染Markdown
        renderer = DOCXRenderer(doc)
        markdown(input_content, renderer)
        
        # 保存为二进制数据
        import io
        output = io.BytesIO()
        doc.save(output)
        output.seek(0)
        
        return output.getvalue()
    
    def _setup_styles(self, doc):
        """设置文档样式"""
        styles = doc.styles
        
        # 设置正文样式
        normal_style = styles['Normal']
        font = normal_style.font
        font.name = 'Microsoft YaHei'
        font.size = Pt(12)
        
        # 设置标题样式
        for i in range(1, 6):
            heading_style = styles[f'Heading {i}']
            font = heading_style.font
            font.name = 'Microsoft YaHei'
            font.size = Pt(14 + (6 - i) * 2)
            font.bold = True
    
    def get_supported_formats(self) -> tuple:
        """获取支持的格式"""
        return ('markdown', 'docx')
