from docx import Document
from docxtpl import DocxTemplate
from stuctor.constants import PREFIX
from docx.oxml.text.paragraph import CT_P
from docx.table import Table
from stuctor.item import TitleItem, TableItemList, Item
from nicegui import ui
from pathlib import Path

template_path = Path.cwd() / "templates"

class Operator:
    """
    参数1: 传入被解析文档名称，不加.docx
    参数2: 传入说明模版文档名称，不加.docx
    参数3: 传入记录模版文档名称，不加.docx
    属性1: item_list - 储存所有Item对象的列表
    """
    # 标题过滤
    TITLE_LIST = ['3', '30', '4', '40', '5', '50', '6', '60', '7', '70']
    BASIC_CAPTER = '6.2'

    def __init__(self, doc_name: str, tp_shuoming_name: str, tp_jilu_name: str, logger: ui.log) -> None:
        # 记录器
        self.logger = logger
        # 被解析文档对象
        self.doc = Document(doc_name)
        # 说明模版文件
        self.tp_shuom = DocxTemplate(template_path / (tp_shuoming_name+'.docx'))
        # 记录模版文件
        self.tp_jilu = DocxTemplate(template_path / (tp_jilu_name+'.docx'))
        # 储存所有item对象的列表
        self.item_list: list[Item] = []
        # 储存大纲章节号排布
        self.c3 = 0
        self.c4 = 0
        self.c5 = 0
        self.c6 = 0
        self.c7 = 0
        self.last_title_item = None

    def main_parse(self, parse_content_strategy: str = 'FPGA'):
        """默认是未解析的，调用该函数开始解析"""
        # 解析开始-这里有点耦合了，其实该请TitleItem对象去处理的
        for ele in self.doc._element.body.iter():  # type: ignore
            if ele.tag.endswith('}p'):
                for child in ele.iter():
                    if child.tag.endswith("pStyle"):
                        rank = child.get(f"{PREFIX}val")
                        title = self.__parse_ele_title(ele)
                        # 标题只有30，40，5，6
                        if rank in self.TITLE_LIST:
                            current_title_item = TitleItem(rank, title)
                            self.item_list.append(current_title_item)
                            # 解析当前章节号
                            self.__parse_current_capter(current_title_item)
            elif ele.tag.endswith('}tbl'):
                table = Table(ele, self.doc)
                if table.cell(0, 0).text == "测试项名称":
                    self.item_list.append(TableItemList(table, self.last_title_item, self.logger, parse_content_strategy))

    # 私有：解析标题文字
    def __parse_ele_title(self, ele: CT_P):
        t_ele = ele.findall(f".//{PREFIX}t")  # type: ignore
        title = ''
        for i in range(len(t_ele)):
            if not t_ele[i].text.isdigit():
                title = title + t_ele[i].text
        return title

    # 私有：解析当前章节号-根据其rank
    def __parse_current_capter(self, current_title_item: TitleItem):
        rank = current_title_item.type
        if rank == '30' or rank == '3':
            self.c3 += 1
            self.c4 = 0
            self.c5 = 0
            self.c6 = 0
            self.c7 = 0
            current_title_item.capter = ".".join([self.BASIC_CAPTER, str(self.c3)])
        elif rank == '40' or rank == '4':
            self.c4 += 1
            self.c5 = 0
            self.c6 = 0
            self.c7 = 0
            current_title_item.capter = '.'.join([self.BASIC_CAPTER, str(self.c3), str(self.c4)])
        elif rank == '50' or rank == '5':
            self.c5 += 1
            self.c6 = 0
            self.c7 = 0
            current_title_item.capter = '.'.join([self.BASIC_CAPTER, str(self.c3), str(self.c4), str(self.c5)])
        elif rank == '60' or rank == '6':
            self.c6 += 1
            self.c7 = 0
            current_title_item.capter = '.'.join([self.BASIC_CAPTER, str(self.c3), str(self.c4), str(self.c6)])
        elif rank == '70' or rank == '7':
            self.c7 += 1
            current_title_item.capter = '.'.join([self.BASIC_CAPTER, str(self.c3), str(self.c4), str(self.c6), str(self.c7)])

        self.last_title_item = current_title_item

    # 最后渲染
    def render(self):
        context = self.__create_context()
        self.tp_shuom.render(context, autoescape = True)
        self.tp_shuom.save("测试说明-输出.docx")
        self.tp_jilu.render(context, autoescape = True)
        self.tp_jilu.save("测试记录-输出.docx")

    # 构造context
    def __create_context(self):
        data_list = []
        for item in self.item_list:
            if isinstance(item, TableItemList):
                for it in item.table_item:
                    temp_item = {
                        'type': 'table',
                        'name': it.name,
                        'ident': it.ident,
                        'zhui': item.zhui,
                        'zong': it.zong,
                        'step': it.step,
                        'csh': it.csh
                    }
                    data_list.append(temp_item)
            elif isinstance(item, TitleItem):
                data_list.append({'type': item.type, 'title': item.title})
        return {"datas": data_list}
