import pandas as pd
import os
import sys

from docx import Document
from copy import deepcopy
from docx.enum.text import WD_COLOR_INDEX
from docx.shared import RGBColor, Pt
import xiaokang
from xiaokang.常用 import 时间_文件_分
from docx.oxml.shared import OxmlElement, qn


def 提取块核心样式(run):
    """
    提取run的核心样式特征（新增背景色），用于判断是否相同
    :param run: run对象
    :return: 包含样式特征的字典
    """
    # 提取背景色（高亮色）：优先取RGB值，无则取枚举值，都无则为None
    # bg_color = None
    # if run.font.highlight_color:
    #     # 处理枚举类型的背景色（如红色、黄色等）
    #     if isinstance(run.font.highlight_color, WD_COLOR_INDEX):
    #         bg_color = run.font.highlight_color.name  # 转为字符串（如"YELLOW"）
    #     # 部分场景下背景色是RGB值（较少见，兼容处理）
    #     elif hasattr(run.font.highlight_color, 'rgb'):
    #         bg_color = run.font.highlight_color.rgb

    rFonts = {}
    try:
        if run._element.rPr is not None and run._element.rPr.rFonts is not None:
            # 读取所有字体相关属性：中文字体、西文字体、等宽字体等
            rFonts["eastAsia"] = rFonts.get(qn('w:eastAsia'))  # 中文字体
            rFonts["ascii"] = rFonts.get(qn('w:ascii'))        # 西文字体
            rFonts["hAnsi"] = rFonts.get(qn('w:hAnsi'))        # 高ANSI字体
            rFonts["cs"] = rFonts.get(qn('w:cs'))              # 复杂脚本字体
    except:
        rFonts = {}

    return {
        "bold": run.bold,
        "italic": run.italic,
        "font_size": run.font.size,
        "font_color": run.font.color.rgb if run.font.color else None,
        "underline": run.underline,
        "font_name": run.font.name,
        # "bg_color": bg_color,  # 新增：文本背景色（高亮色）
        "rFonts": rFonts
    }


def 合并样式相同块(paragraph):
    """
    合并段落中样式相同的相邻run，保留不同样式的run
    :param paragraph: 要处理的段落对象
    """
    if len(paragraph.runs) <= 1:
        return paragraph  # 只有1个run，无需合并

    list_sz = 0
    old_style = 提取块核心样式(paragraph.runs[list_sz])
    # 遍历剩余run，分组合并
    for f1, run in enumerate(paragraph.runs[1:], 1):
        new_style = 提取块核心样式(run)
        if new_style == old_style:
            paragraph.runs[list_sz].text += run.text
            run.text = ''
        elif run.text == '':
            continue
        else:
            list_sz = f1
            old_style = new_style

    def 删除文档的字段的块(sc_sun):  # 删除word文档里面的块
        sc_a = sc_sun._element
        sc_a.getparent().remove(sc_a)
        sc_a._p = sc_a._element = None

    a = paragraph.runs
    f1 = 0
    while f1 < len(a):
        if a[f1].text == '':
            del a[f1]
        else:
            f1 += 1

    return paragraph


def 读docx(文件路径):
    """
    读取docx文件，返回文档对象
    """
    try:
        doc = Document(文件路径)

        for f2, f1 in enumerate(doc.paragraphs, 1):
            合并样式相同块(f1)

        for f1 in doc.tables:  # 全表格
            for f2 in f1._cells:  # 每个单元格
                for f3 in f2.paragraphs:  # 每个单元格中的段落
                    合并样式相同块(f3)

        return doc
    except:
        print(xiaokang.报错信息('json'))
        sys.exit()


def 读xlsx(文件路径):
    try:
        df = pd.read_excel(文件路径)
        data_dict = df.to_dict(orient="records")
        return data_dict
    except:
        print(xiaokang.报错信息('json'))
        sys.exit()


def 批量docx(docx模板路径, xlsx表格路径, 输出目录):
    # 示例：测试合并效果

    if not os.path.exists(docx模板路径):
        print("docx模板不存在")
        sys.exit()
    if not os.path.exists(xlsx表格路径):
        print("xlsx数据不存在")
        sys.exit()
    if not os.path.exists(输出目录):
        os.makedirs(输出目录)

    docx = 读docx(docx模板路径)
    xlsx = 读xlsx(xlsx表格路径)

    temp_copy_path = f'{时间_文件_分()}.docx'
    docx文件名名称 = os.path.split(docx模板路径)[1]

    doc = docx.save(temp_copy_path)
    try:
        for f6, f1 in enumerate(xlsx, 1):
            doc = Document(temp_copy_path)

            # 段落
            for f2 in doc.paragraphs:
                for f3 in f2.runs:
                    try:
                        f3.text = f3.text.format(**f1)
                    except KeyError as e:
                        print(f'表格缺少对象【{e}】')
                    except Exception as e:
                        print(f'未知报错：{e}')

            for f2 in doc.tables:
                for f3 in f2._cells:
                    for f4 in f3.paragraphs:
                        for f5 in f4.runs:
                            try:
                                f5.text = f5.text.format(**f1)
                            except KeyError as e:
                                print(f'表格缺少对象【{e}】')
                            except Exception as e:
                                print(f'未知报错：{e}')

            doc.save(f'{os.path.abspath(os.path.join(输出目录, docx文件名名称.format(**f1)))}')
            print(f"完成【{f6}/{len(xlsx)}】：{docx文件名名称.format(**f1)}")
    except:
        print(xiaokang.报错信息('json'))
        os.remove(temp_copy_path)
        sys.exit()


if __name__ == '__main__':
    pass
    # docx模板路径 = r"C:\Users\XiaoKang\Desktop\python预制库\xiaokang\tests\专家邀请函（{专家名字}）.docx"
    # xlsx表格路径 = r"C:\Users\XiaoKang\Desktop\python预制库\xiaokang\tests\1.xlsx"
    # 输出目录 = r'C:\Users\XiaoKang\Desktop\python预制库\xiaokang\tests\cs1'

    # 批量docx(docx模板路径, xlsx表格路径, 输出目录)
