from fastapi import APIRouter, Request, Depends
from fastapi.responses import JSONResponse, StreamingResponse
import sys
import os
import json
import logging
import shutil
from pathlib import Path
from core.AnalysisReport import *
from core.AnalysisReportPPTX import *
from nacos_fast import *
from conf.conf_fastapi import app_config
from conf.conf_fastapi import AppConfig


def get_app_config():
    return app_config


router = APIRouter()


@router.post("/DownWordProgressMessageReturnReport")
async def DownWordProgressMessageReturnReport_handler(request: Request, config: AppConfig = Depends(get_app_config)):
    try:
        # 解析请求体
        body = await request.body()
        receive_data = json.loads(body.decode('utf-8'))

        if isinstance(receive_data, str):
            receive_data = json.loads(receive_data)

        print('接收到的json数据=' + str(receive_data))
        PlatID = receive_data['PlatID']
        ProjID = ''  # receive_data['ProjID']
        TempID = receive_data['TempID']
        NewFileName = str(receive_data['NewFileName']).strip()
        templateFileServerUrl = ""
        if receive_data.get('CasesCondition') is not None:
            CasesCondition = receive_data['CasesCondition']
        else:
            CasesCondition = None
        if receive_data.get('caseFilter') is not None:
            caseFilter = receive_data['caseFilter']
        else:
            caseFilter = None
        if receive_data.get('fileGroup') is not None:
            fileGroup = receive_data['fileGroup']
        else:
            fileGroup = None
        if receive_data.get('edition') is not None:
            edition = receive_data['edition']
        else:
            edition = ""
        if receive_data.get('TokenID') is not None:
            TokenID = receive_data['TokenID']
        else:
            TokenID = ""
        if receive_data.get('serverUrl') is not None:
            serverUrl = receive_data['serverUrl']
            mongodb_cfg, template_url = nacos_fast(serverUrl, config.mongodb_cfg_map, config.templateFileServerUrlMap)
            maxResponseCount = config.maxResponseCount
            redis_cfg = config.redis_cfg_map
        else:
            mongodb_cfg, redis_cfg = "readInfo", ""
        if receive_data.get('updateFlag') is not None:
            updateFlag = receive_data.get('updateFlag')
        else:
            updateFlag = False
        if receive_data.get('updatePhraseFlag') is not None:
            updatePhraseFlag = receive_data.get('updatePhraseFlag')
        else:
            updatePhraseFlag = False

        filePathName = myReportMainJava(PlatID, ProjID, TempID, TokenID, mongodb_cfg, caseFilter, fileGroup,
                                        NewFileName, edition, updateFlag, templateFileServerUrl, redis_cfg,
                                        updatePhraseFlag, CasesCondition)
        
        # 读取文件并返回
        async def file_streamer():
            with open(filePathName, 'rb') as f:
                while True:
                    b = f.read(8096)
                    if not b:
                        break
                    yield b
        
        return StreamingResponse(file_streamer(), media_type="application/octet-stream")
    except Exception as e:
        logging.error("%s" % str(e) + " " + str(request.client.host))
        return JSONResponse({"code": "参数错误", "msg": str(e)})


@router.post("/reportfile2")
async def DownWordProgressMessageReturnReport2_handler(request: Request, config: AppConfig = Depends(get_app_config)):
    try:
        # 解析请求体
        body = await request.body()
        receive_data = json.loads(body.decode('utf-8'))

        if isinstance(receive_data, str):
            receive_data = json.loads(receive_data)

        print('接收到的json数据=' + str(receive_data))
        PlatID = receive_data['PlatID']
        ProjID = ''  # receive_data['ProjID']
        TempID = receive_data['TempID']
        NewFileName = str(receive_data['NewFileName']).strip()
        templateFileServerUrl = ""
        if receive_data.get('CasesCondition') is not None:
            CasesCondition = receive_data['CasesCondition']
        else:
            CasesCondition = None
        if receive_data.get('caseFilter') is not None:
            caseFilter = receive_data['caseFilter']
        else:
            caseFilter = None
        if receive_data.get('fileGroup') is not None:
            fileGroup = receive_data['fileGroup']
        else:
            fileGroup = None
        if receive_data.get('edition') is not None:
            edition = receive_data['edition']
        else:
            edition = ""
        if receive_data.get('TokenID') is not None:
            TokenID = receive_data['TokenID']
        else:
            TokenID = ""
        if receive_data.get('serverUrl') is not None:
            serverUrl = receive_data['serverUrl']
            mongodb_cfg, templateFileServerUrl = nacos_fast(serverUrl, config.mongodb_cfg_map, config.templateFileServerUrlMap)
            maxResponseCount = config.maxResponseCount
            redis_cfg = config.redis_cfg_map
        else:
            mongodb_cfg, redis_cfg = "readInfo", ""
        if receive_data.get('updateFlag') is not None:
            updateFlag = receive_data.get('updateFlag')
        else:
            updateFlag = False
        if receive_data.get('updatePhraseFlag') is not None:
            updatePhraseFlag = receive_data.get('updatePhraseFlag')
        else:
            updatePhraseFlag = False
        
        checkFlag, fileType = templateCheck(TempID, edition, TokenID, templateFileServerUrl)
        if checkFlag and fileType == 'pptx':
            myReportPPTXMainJava(PlatID, ProjID, TempID, TokenID, mongodb_cfg, caseFilter, fileGroup, NewFileName,
                              edition, updateFlag, templateFileServerUrl, redis_cfg, updatePhraseFlag, CasesCondition)
        else:
            myReportMainJava(PlatID, ProjID, TempID, TokenID, mongodb_cfg, caseFilter, fileGroup, NewFileName,
                             edition, updateFlag, templateFileServerUrl, redis_cfg, updatePhraseFlag, CasesCondition)
        
        return JSONResponse({"status": "success"})
    except Exception as e:
        logging.error("%s" % str(e) + " " + str(request.client.host))
        return JSONResponse({"code": "参数错误", "msg": str(e)})


@router.post("/reportcancel")
async def DownWordProgressMessageCancelReport_handler(request: Request, config: AppConfig = Depends(get_app_config)):
    try:
        # 解析请求体
        body = await request.body()
        receive_data = json.loads(body.decode('utf-8'))

        if isinstance(receive_data, str):
            receive_data = json.loads(receive_data)

        print('接收到的json数据=' + str(receive_data))
        PlatID = receive_data['PlatID']
        ProjID = ''  # receive_data['ProjID']
        TempID = receive_data['TempID']
        if str(os.path.abspath(os.curdir)).find("controllers") > 0:
            filePath = os.path.abspath(os.curdir).replace("controllers", "docx")
        else:
            filePath = os.path.join(os.path.abspath(os.curdir), "docx")
        reportPath = os.path.join(filePath, 'report')
        reportList = os.listdir(reportPath)
        for reportItem in reportList:
            f_path = os.path.join(reportPath, reportItem)
            if (reportItem.find('.docx') > -1 or reportItem.find(TempID) > -1) and Path(f_path).is_file():
                os.remove(f_path)
            if reportItem.find(TempID) > -1 and os.path.isdir(f_path):
                shutil.rmtree(f_path)
        templatePath = os.path.join(filePath, 'charts')
        templateList = os.listdir(templatePath)
        for templateItem in templateList:
            t_path = os.path.join(templatePath, templateItem)
            if templateItem.find(TempID) > -1 and Path(t_path).is_file():
                os.remove(t_path)
        
        return JSONResponse({"status": "success"})
    except Exception as e:
        logging.error("%s" % str(e) + " " + str(request.client.host))
        return JSONResponse({"code": "参数错误", "msg": str(e)})


@router.post("/reportname")
async def DownWordProgressMessageReportName_handler(request: Request, config: AppConfig = Depends(get_app_config)):
    try:
        # 解析请求体
        body = await request.body()
        receive_data = json.loads(body.decode('utf-8'))

        if isinstance(receive_data, str):
            receive_data = json.loads(receive_data)

        print('接收到的json数据=' + str(receive_data))
        PlatID = receive_data['PlatID']
        ProjID = ''  # receive_data['ProjID']
        TempID = receive_data['TempID']
        if receive_data.get('CasesCondition') is not None:
            CasesCondition = receive_data['CasesCondition']
        else:
            CasesCondition = None
        fileGroup = receive_data['fileGroup']
        if receive_data.get('serverUrl') is not None:
            serverUrl = receive_data['serverUrl']
            mongodb_cfg, template_url = nacos_fast(serverUrl, config.mongodb_cfg_map, config.templateFileServerUrlMap)
            maxResponseCount = config.maxResponseCount
            redis_cfg = config.redis_cfg_map
        else:
            mongodb_cfg, redis_cfg = "readInfo", ""
        if str(os.path.abspath(os.curdir)).find("controllers") > 0:
            filePath = os.path.abspath(os.curdir).replace("controllers", "docx")
        else:
            filePath = os.path.join(os.path.abspath(os.curdir), "docx")
        reportPath = os.path.join(filePath, 'report')
        reportList = os.listdir(reportPath)
        reportName, reportFlag, reportCount = '报告未生成', False, 0
        for reportItem in reportList:
            f_path = os.path.join(reportPath, reportItem)
            if reportItem.find(TempID) > -1 and os.path.isdir(f_path):
                reportFlag = True
                for f_pathItem in os.listdir(f_path):
                    reportCount += 1
                    if reportName == '报告未生成':
                        reportName = f_pathItem
                    else:
                        reportName += ';'
                        reportName += f_pathItem
        myReportName(PlatID, ProjID, TempID, mongodb_cfg, fileGroup[reportCount], CasesCondition)
        if reportName == '报告未生成' and not reportFlag:
            for reportItem in reportList:
                if str(reportItem).find('.zip') > 0 and str(reportItem).find(TempID) > -1:
                    reportName = '报告已完成'
        
        return JSONResponse({"reportName": reportName})
    except Exception as e:
        logging.error("%s" % str(e) + " " + str(request.client.host))
        return JSONResponse({"code": "参数错误", "msg": str(e)})


@router.get("/reportdown_get")
async def DownWordProgressMessageDownReport_get_handler(request: Request, config: AppConfig = Depends(get_app_config)):
    try:
        templateID = request.query_params.get('TempID')
        print(templateID)
        if str(os.path.abspath(os.curdir)).find("controllers") > 0:
            filePathPPTX = os.path.abspath(os.curdir).replace("controllers", "pptx")
        else:
            filePathPPTX = os.path.join(os.path.abspath(os.curdir), "pptx")

        if str(os.path.abspath(os.curdir)).find("controllers") > 0:
            filePathDOCX = os.path.abspath(os.curdir).replace("controllers", "docx")
        else:
            filePathDOCX = os.path.join(os.path.abspath(os.curdir), "docx")
        reportListPPTX = os.listdir(os.path.join(filePathPPTX, 'report'))
        reportListDOCX = os.listdir(os.path.join(filePathDOCX, 'report'))
        reportPathOut, reportTime = '', 0
        for reportItem in reportListPPTX:
            f_path = os.path.join(os.path.join(filePathPPTX, 'report'), reportItem)
            if os.path.isdir(f_path):
                pass
            else:
                if str(reportItem).find('.zip') > 0 and str(reportItem).find(templateID) > -1:
                    if int(str(reportItem)[24:44]) > reportTime:
                        reportPathOut = f_path
                        reportTime = int(str(reportItem)[24:44])
        for reportItem in reportListDOCX:
            f_path = os.path.join(os.path.join(filePathDOCX, 'report'), reportItem)
            if os.path.isdir(f_path):
                pass
            else:
                if str(reportItem).find('.zip') > 0 and str(reportItem).find(templateID) > -1:
                    if int(str(reportItem)[24:44]) > reportTime:
                        reportPathOut = f_path
                        reportTime = int(str(reportItem)[24:44])
        
        # 读取文件并返回
        async def file_streamer():
            with open(reportPathOut, 'rb') as f:
                while True:
                    b = f.read(8096)
                    if not b:
                        break
                    yield b
        
        return StreamingResponse(file_streamer(), media_type="application/octet-stream")
    except Exception as e:
        logging.error("%s" % str(e) + " " + str(request.client.host))
        return JSONResponse({"code": "参数错误", "msg": str(e)})


@router.post("/reportdown")
async def DownWordProgressMessageDownReport_post_handler(request: Request, config: AppConfig = Depends(get_app_config)):
    try:
        # 解析请求体
        body = await request.body()
        receive_data = json.loads(body.decode('utf-8'))

        if isinstance(receive_data, str):
            receive_data = json.loads(receive_data)

        print('接收到的json数据=' + str(receive_data))
        PlatID = receive_data['PlatID']
        ProjID = ''  # receive_data['ProjID']
        TempID = receive_data['TempID']
        if str(os.path.abspath(os.curdir)).find("controllers") > 0:
            filePathPPTX = os.path.abspath(os.curdir).replace("controllers", "pptx")
        else:
            filePathPPTX = os.path.join(os.path.abspath(os.curdir), "pptx")

        if str(os.path.abspath(os.curdir)).find("controllers") > 0:
            filePathDOCX = os.path.abspath(os.curdir).replace("controllers", "docx")
        else:
            filePathDOCX = os.path.join(os.path.abspath(os.curdir), "docx")
        reportListPPTX = os.listdir(os.path.join(filePathPPTX, 'report'))
        reportListDOCX = os.listdir(os.path.join(filePathDOCX, 'report'))
        reportPathOut, reportTime = '', 0
        for reportItem in reportListPPTX:
            f_path = os.path.join(os.path.join(filePathPPTX, 'report'), reportItem)
            if os.path.isdir(f_path):
                pass
            else:
                if str(reportItem).find('.zip') > 0 and str(reportItem).find(TempID) > -1:
                    if int(str(reportItem)[24:44]) > reportTime:
                        reportPathOut = f_path
                        reportTime = int(str(reportItem)[24:44])
        for reportItem in reportListDOCX:
            f_path = os.path.join(os.path.join(filePathDOCX, 'report'), reportItem)
            if os.path.isdir(f_path):
                pass
            else:
                if str(reportItem).find('.zip') > 0 and str(reportItem).find(TempID) > -1:
                    if int(str(reportItem)[24:44]) > reportTime:
                        reportPathOut = f_path
                        reportTime = int(str(reportItem)[24:44])
        
        # 读取文件并返回
        async def file_streamer():
            with open(reportPathOut, 'rb') as f:
                while True:
                    b = f.read(8096)
                    if not b:
                        break
                    yield b
        
        return StreamingResponse(file_streamer(), media_type="application/octet-stream")
    except Exception as e:
        logging.error("%s" % str(e) + " " + str(request.client.host))
        return JSONResponse({"code": "参数错误", "msg": str(e)})


@router.post("/largeScreen")
async def DownJsonProgressMessageLargeScreen_handler(request: Request, config: AppConfig = Depends(get_app_config)):
    try:
        # 解析请求体
        body = await request.body()
        receive_data = json.loads(body.decode('utf-8'))

        if isinstance(receive_data, str):
            receive_data = json.loads(receive_data)

        print('接收到的json数据=' + str(receive_data))
        PlatID = receive_data['PlatID']
        ProjID = ''  # receive_data['ProjID']
        TempID = receive_data['TempID']
        if receive_data.get('CasesCondition') is not None:
            CasesCondition = receive_data['CasesCondition']
        else:
            CasesCondition = None
        if receive_data.get('indicesModule') is not None:
            indicesModule = receive_data['indicesModule']
        else:
            indicesModule = None
        if receive_data.get('serverUrl') is not None:
            serverUrl = receive_data['serverUrl']
            mongodb_cfg, template_url = nacos_fast(serverUrl, config.mongodb_cfg_map, config.templateFileServerUrlMap)
            maxResponseCount = config.maxResponseCount
            redis_cfg = config.redis_cfg_map
        else:
            mongodb_cfg, redis_cfg = "readInfo", ""
        largeScreenJson = myLargeScreenMain(PlatID, ProjID, TempID, mongodb_cfg, indicesModule, CasesCondition)
        if largeScreenJson is None: 
            largeScreenJson = ''

        return JSONResponse({"largeScreenJson": largeScreenJson})
    except Exception as e:
        logging.error("%s" % str(e) + " " + str(request.client.host))
        return JSONResponse({"code": "参数错误", "msg": str(e)})


# 辅助函数
def templateCheck(tempID, templateEdition, tokenID, templateFileServerUrl):
    tempCheckFlag, tempFileType = False, 'docx'
    try:
        import urllib.parse
        import requests
        query = {"templateId": str(tempID), "edition": templateEdition}
        if templateFileServerUrl != "":
            url = str(templateFileServerUrl).strip() + '/report/downloadReportTemplateWord'
        else:
            url = 'http://192.168.2.160:8851/report/downloadReportTemplateWord'
        url = url + '?' + urllib.parse.urlencode(query)

        if tokenID != "":
            headers = {'Authorization': 'token = ' + tokenID}
            r = requests.post(url, headers=headers)
        else:
            r = requests.post(url)
        content_disposition = r.headers.get('Content-Disposition')
        if content_disposition:
            # 使用简单的字符串操作来提取文件名
            filename = content_disposition.split('=')[1].strip().replace('"', '')
            if str(filename).find('.pptx') > 0:
                tempFileType = 'pptx'
        tempCheckFlag = True
    except Exception as ex:
        tempCheckFlag = False
    finally:
        return tempCheckFlag, tempFileType


