"""
HTML 到 Markdown 转换器

用于将 HTML 格式（如 OCR 返回的 HTML）转换为 Markdown 格式。
使用 markdownify 库，支持表格、列表、标题等复杂结构转换。

【修改记录】2025-03-27: 更新文档说明，移除 MinerU 特定引用
"""

from __future__ import annotations

import re
from typing import Optional

try:
    import markdownify
    MARKDOWNIFY_AVAILABLE = True
except ImportError:
    MARKDOWNIFY_AVAILABLE = False


class HTMLToMarkdownConverter:
    """HTML 到 Markdown 转换器"""
    
    def __init__(self):
        """初始化转换器"""
        if not MARKDOWNIFY_AVAILABLE:
            raise ImportError(
                "markdownify 库未安装。请运行: pip install markdownify"
            )
    
    def convert(self, html_content: str, **options) -> str:
        """
        将 HTML 转换为 Markdown
        
        参数:
            html_content: HTML 内容
            **options: 转换选项
                - heading_style: 标题样式 ("ATX" 或 "SETEXT"), 默认 "ATX"
                - bullets: 列表符号, 默认 "*"
                - strip: 是否删除未知标签, 默认 False
                - convert_tables: 是否转换表格, 默认 True
                - escape_asterisks: 是否转义星号, 默认 False
                - escape_underscores: 是否转义下划线, 默认 False
        
        返回:
            Markdown 格式文本
        """
        if not html_content or not html_content.strip():
            return ""
        
        # 默认选项
        default_options = {
            'heading_style': 'ATX',  # ATX: # 标题, SETEXT: 下划线标题
            'bullets': '*',          # 列表符号
            'convert': ['b', 'strong', 'i', 'em', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 
                       'ul', 'ol', 'li', 'br', 'hr', 'a', 'img', 'table', 'tr', 'td', 'th'],
        }
        
        # 合并用户选项（排除冲突的 strip 参数）
        for key, value in options.items():
            if key != 'strip':  # 避免与 convert 冲突
                default_options[key] = value
        
        try:
            # 使用 markdownify 转换
            markdown_content = markdownify.markdownify(
                html_content,
                **default_options
            )
            
            # 后处理：清理多余空行、修复表格格式等
            markdown_content = self._post_process(markdown_content)
            
            return markdown_content
            
        except Exception as e:
            print(f"[WARN] HTML 转 Markdown 失败: {e}")
            # 降级方案：返回清理后的纯文本
            return self._fallback_convert(html_content)
    
    def _post_process(self, markdown_content: str) -> str:
        """
        后处理 Markdown 内容
        
        1. 清理多余空行
        2. 修复表格格式
        3. 清理 HTML 标签残留
        """
        if not markdown_content:
            return ""
        
        # 1. 清理多余空行（超过2个连续空行改为2个）
        markdown_content = re.sub(r'\n{3,}', '\n\n', markdown_content)
        
        # 2. 修复表格分隔符（markdownify 生成的表格可能需要调整）
        # 确保表格分隔行格式正确 |---|---|
        markdown_content = self._fix_table_format(markdown_content)
        
        # 3. 清理残留的 HTML 标签（如 <span>, <div> 等）
        markdown_content = self._clean_html_tags(markdown_content)
        
        # 4. 清理行首行尾空格
        lines = [line.strip() for line in markdown_content.split('\n')]
        markdown_content = '\n'.join(lines)
        
        # 5. 再次清理多余空行
        markdown_content = re.sub(r'\n{3,}', '\n\n', markdown_content)
        
        return markdown_content.strip()
    
    def _fix_table_format(self, markdown_content: str) -> str:
        """修复表格格式"""
        lines = markdown_content.split('\n')
        result_lines = []
        i = 0
        
        while i < len(lines):
            line = lines[i]
            
            # 检测表格行（以 | 开头和结尾）
            if line.strip().startswith('|') and line.strip().endswith('|'):
                # 检查下一行是否是分隔行
                if i + 1 < len(lines):
                    next_line = lines[i + 1]
                    # 如果下一行不是分隔符行，则插入分隔行
                    if not re.match(r'\s*\|[-:|\s]+\|', next_line):
                        # 计算列数
                        col_count = len([c for c in line.split('|') if c.strip()])
                        if col_count > 0:
                            separator = '|' + '|'.join(['---'] * col_count) + '|'
                            result_lines.append(line)
                            result_lines.append(separator)
                            i += 1
                            continue
                
                # 修复分隔行格式
                if re.match(r'\s*\|[-:|\s]+\|', line):
                    # 标准化分隔行
                    cells = [cell.strip() for cell in line.split('|') if cell.strip()]
                    fixed_cells = []
                    for cell in cells:
                        # 确保是标准分隔符格式
                        if set(cell) <= set('-:| '):
                            fixed_cells.append('---')
                        else:
                            fixed_cells.append(cell)
                    if fixed_cells:
                        line = '|' + '|'.join(fixed_cells) + '|'
            
            result_lines.append(line)
            i += 1
        
        return '\n'.join(result_lines)
    
    def _clean_html_tags(self, markdown_content: str) -> str:
        """清理残留的 HTML 标签"""
        # 清理常见的内联标签，但保留内容
        tags_to_remove = ['span', 'div', 'font', 'b', 'i', 'em', 'strong']
        
        for tag in tags_to_remove:
            # 移除开始标签 <tag ...>
            markdown_content = re.sub(
                rf'<{tag}[^>]*>', 
                '', 
                markdown_content, 
                flags=re.IGNORECASE
            )
            # 移除结束标签 </tag>
            markdown_content = re.sub(
                rf'</{tag}>', 
                '', 
                markdown_content, 
                flags=re.IGNORECASE
            )
        
        # 清理注释
        markdown_content = re.sub(r'<!--.*?-->', '', markdown_content, flags=re.DOTALL)
        
        # 清理 &nbsp; 等 HTML 实体
        markdown_content = markdown_content.replace('&nbsp;', ' ')
        markdown_content = markdown_content.replace('&lt;', '<')
        markdown_content = markdown_content.replace('&gt;', '>')
        markdown_content = markdown_content.replace('&amp;', '&')
        markdown_content = markdown_content.replace('&quot;', '"')
        
        return markdown_content
    
    def _fallback_convert(self, html_content: str) -> str:
        """
        降级转换方案：当 markdownify 失败时使用
        
        简单的标签剥离，保留文本内容
        """
        # 移除 script 和 style 标签及其内容
        text = re.sub(r'<script[^>]*>.*?</script>', '', html_content, flags=re.DOTALL | re.IGNORECASE)
        text = re.sub(r'<style[^>]*>.*?</style>', '', text, flags=re.DOTALL | re.IGNORECASE)
        
        # 将 <br>, <p> 等转为换行
        text = re.sub(r'<br\s*/?>', '\n', text, flags=re.IGNORECASE)
        text = re.sub(r'</p>', '\n\n', text, flags=re.IGNORECASE)
        
        # 剥离所有 HTML 标签
        text = re.sub(r'<[^>]+>', '', text)
        
        # 清理 HTML 实体
        text = text.replace('&nbsp;', ' ')
        text = text.replace('&lt;', '<')
        text = text.replace('&gt;', '>')
        text = text.replace('&amp;', '&')
        
        # 清理多余空行
        text = re.sub(r'\n{3,}', '\n\n', text)
        
        return text.strip()


# 全局转换器实例
_converter: Optional[HTMLToMarkdownConverter] = None


def get_converter() -> HTMLToMarkdownConverter:
    """获取全局转换器实例（单例模式）"""
    global _converter
    if _converter is None:
        _converter = HTMLToMarkdownConverter()
    return _converter


def convert_html_to_markdown(html_content: str, **options) -> str:
    """
    便捷函数：将 HTML 转换为 Markdown
    
    参数:
        html_content: HTML 内容
        **options: 转换选项
    
    返回:
        Markdown 格式文本
    """
    try:
        converter = get_converter()
        return converter.convert(html_content, **options)
    except ImportError:
        # 如果 markdownify 未安装，使用降级方案
        print("[WARN] markdownify 未安装，使用降级转换方案")
        converter = HTMLToMarkdownConverter.__new__(HTMLToMarkdownConverter)
        return converter._fallback_convert(html_content)
