from void_terminal.toolbox import update_ui
from void_terminal.toolbox import CatchException, report_exception
from void_terminal.toolbox import write_history_to_file, promote_file_to_downloadzone
from void_terminal.crazy_functions.crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
fast_debug = False


def ParseDocx(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt):
    import time, os
    # pip install python-docx for docx format, Cross-platform
    # pip install pywin32 for doc format, Only supports Win platform
    for index, fp in enumerate(file_manifest):
        if fp.split(".")[-1] == "docx":
            from docx import Document
            doc = Document(fp)
            file_content = "\n".join([para.text for para in doc.paragraphs])
        else:
            try:
                import win32com.client
                word = win32com.client.Dispatch("Word.Application")
                word.visible = False
                # Open file
                doc = word.Documents.Open(os.getcwd() + '/' + fp)
                # file_content = doc.Content.Text
                doc = word.ActiveDocument
                file_content = doc.Range().Text
                doc.Close()
                word.Quit()
            except:
                raise RuntimeError('Please convert .doc documents to .docx documents first. ')

        print(file_content)
        # The file name inside private_upload is prone to garbled characters after unzipping（RAR and 7z formats are normal）, So you can only analyze the content of the article, Do not enter the file name
        from void_terminal.crazy_functions.crazy_utils import breakdown_txt_to_satisfy_token_limit_for_pdf
        from void_terminal.request_llms.bridge_all import model_info
        max_token = model_info[llm_kwargs['llm_model']]['max_token']
        TOKEN_LIMIT_PER_FRAGMENT = max_token * 3 // 4
        paper_fragments = breakdown_txt_to_satisfy_token_limit_for_pdf(
            txt=file_content,  
            get_token_fn=model_info[llm_kwargs['llm_model']]['token_cnt'], 
            limit=TOKEN_LIMIT_PER_FRAGMENT
        )
        this_paper_history = []
        for i, paper_frag in enumerate(paper_fragments):
            i_say = f'Please summarize the following article fragment in Chinese, The file name is{os.path.relpath(fp, project_folder)}, The content of the article is ```{paper_frag}```'
            i_say_show_user = f'Please summarize the following article fragment: {os.path.abspath(fp)}The{i+1}/{len(paper_fragments)}fragment. '
            gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
                inputs=i_say, 
                inputs_show_user=i_say_show_user, 
                llm_kwargs=llm_kwargs,
                chatbot=chatbot, 
                history=[],
                sys_prompt="Summarize the article. "
            )

            chatbot[-1] = (i_say_show_user, gpt_say)
            history.extend([i_say_show_user,gpt_say])
            this_paper_history.extend([i_say_show_user,gpt_say])

        # All segments of the article have been summarized, If the article is cut into pieces, 
        if len(paper_fragments) > 1:
            i_say = f"According to the above dialogue, Summarize the article{os.path.abspath(fp)}The main content of. "
            gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
                inputs=i_say, 
                inputs_show_user=i_say, 
                llm_kwargs=llm_kwargs,
                chatbot=chatbot, 
                history=this_paper_history,
                sys_prompt="Summarize the article. "
            )

            history.extend([i_say,gpt_say])
            this_paper_history.extend([i_say,gpt_say])

        res = write_history_to_file(history)
        promote_file_to_downloadzone(res, chatbot=chatbot)
        chatbot.append(("Are you done?？", res))
        yield from update_ui(chatbot=chatbot, history=history) # Refresh the page

    res = write_history_to_file(history)
    promote_file_to_downloadzone(res, chatbot=chatbot)
    chatbot.append(("Are all files summarized?？", res))
    yield from update_ui(chatbot=chatbot, history=history) # Refresh the page


@CatchException
def SummarizingWordDocuments(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
    import glob, os

    # Basic information：Function, contributor
    chatbot.append([
        "Function plugin feature？",
        "Batch summarize Word documents. Function plugin contributor: JasonGuo1. Attention, If it is a .doc file, Please convert it to .docx format first. "])
    yield from update_ui(chatbot=chatbot, history=history) # Refresh the page

    # Attempt to import dependencies, If dependencies are missing, Give installation suggestions
    try:
        from docx import Document
    except:
        report_exception(chatbot, history,
                         a=f"Parsing project: {txt}",
                         b=f"Failed to import software dependencies. Using this module requires additional dependencies, Installation method```pip install --upgrade python-docx pywin32```. ")
        yield from update_ui(chatbot=chatbot, history=history) # Refresh the page
        return

    # Clear history, To avoid input overflow
    history = []

    # Checking input parameters, If no input parameters are given, Exit directly
    if os.path.exists(txt):
        project_folder = txt
    else:
        if txt == "": txt = 'Empty input field'
        report_exception(chatbot, history, a=f"Parsing project: {txt}", b=f"Cannot find local project or do not have access: {txt}")
        yield from update_ui(chatbot=chatbot, history=history) # Refresh the page
        return

    # Search for the list of files to be processed
    if txt.endswith('.docx') or txt.endswith('.doc'):
        file_manifest = [txt]
    else:
        file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.docx', recursive=True)] + \
                        [f for f in glob.glob(f'{project_folder}/**/*.doc', recursive=True)]

    # If no files are found
    if len(file_manifest) == 0:
        report_exception(chatbot, history, a=f"Parsing project: {txt}", b=f"Cannot find any .docx or .doc files: {txt}")
        yield from update_ui(chatbot=chatbot, history=history) # Refresh the page
        return

    # Start executing the task formally
    yield from ParseDocx(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
