package com.zt.plat.module.qms.business.reportdoc.service;

import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zt.plat.framework.common.exception.ServiceException;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.util.object.BeanUtils;
import com.zt.plat.framework.security.core.LoginUser;
import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils;
import com.zt.plat.module.infra.api.file.FileApi;
import com.zt.plat.module.infra.api.file.dto.FileCreateReqDTO;
import com.zt.plat.module.infra.api.file.dto.FileRespDTO;
import com.zt.plat.module.qms.business.reportdoc.controller.vo.ReportDocumentFileSaveReqVO;
import com.zt.plat.module.qms.business.reportdoc.dal.dataobject.ReportDocumentFileDO;
import com.zt.plat.module.qms.business.reportdoc.dal.dataobject.ReportDocumentMainDO;
import com.zt.plat.module.qms.business.reportdoc.dal.dataobject.ReportDocumentTypeDO;
import com.zt.plat.module.qms.common.data.dal.dataobject.DataTemplateDO;
import com.zt.plat.module.qms.common.data.service.DataTemplateService;
import com.zt.plat.module.qms.core.code.SequenceUtil;
import com.zt.plat.module.system.api.iwork.IWorkIntegrationApi;
import com.zt.plat.module.system.api.iwork.dto.IWorkOperationRespDTO;
import com.zt.plat.module.system.api.iwork.dto.IWorkWorkflowCreateReqDTO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Optional;

import static com.zt.plat.module.qms.enums.ErrorCodeConstants.REPORT_DOCUMENT_FILE_NOT_EXISTS;

/*
* 处理报告附件和发起iwork流程
* */
@Service("reportDocumentAssistService")
@Slf4j
public class ReportDocumentAssistService {
    @Resource
    private IWorkIntegrationApi iWorkIntegrationApi;

    @Value("${zzjc.html2pdf.addr:}")
    private String html2pdfAddr;

    @Resource private ReportDocumentDataService reportDocumentDataService;
    @Resource private ReportDocumentTypeService reportDocumentTypeService;
    @Resource private ReportDocumentFileService reportDocumentFileService;
    @Resource private DataTemplateService dataTemplateService;
    @Resource private SequenceUtil sequenceUtil;
    @Resource private FileApi fileApi;

    private String sequenceKey = "QMS_REPORT_IWORK_CODE";

    // todo 判断是否更新pdf
    public boolean checkUpdateDocFile(JSONObject variables){
        return true;
    }

    /*
     * 更新报告附件，并发起iwork流程*/
    public void updateDocFileAndCreateIWorkflow(JSONObject variables, ReportDocumentMainDO entity) throws IOException {
//        boolean updateDocFileFlag = true;
        boolean createIworkWorkflowFlag = false;
        JSONArray bpmFieldExtensions = variables.getJSONArray("bpmFieldExtensions");
        if(bpmFieldExtensions == null)
            bpmFieldExtensions = new JSONArray();
        for(int i = 0; i < bpmFieldExtensions.size(); i++){
            JSONObject extension = bpmFieldExtensions.getJSONObject(i);
            String fieldName = extension.getString("fieldName");
            String stringValue = extension.getString("stringValue");
            if(fieldName.equalsIgnoreCase("createiworkflow") && stringValue.equals("1")){
                createIworkWorkflowFlag = true;
                break;
            }
        }
        ReportDocumentFileDO docFile = generatePdf(entity);
        if(createIworkWorkflowFlag){
            CommonResult<IWorkOperationRespDTO> iworkkResult = createIWorkflow(entity, docFile);
            log.error("iworkkResult: " + JSONObject.toJSONString(iworkkResult));
        }
    }

    /*
     * 发起iwork用印*/
    public CommonResult<IWorkOperationRespDTO> createIWorkflow(ReportDocumentMainDO entity, ReportDocumentFileDO docFile) {
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        IWorkWorkflowCreateReqDTO dto = new IWorkWorkflowCreateReqDTO();
        dto.setOperatorUserId(String.valueOf(loginUser.getId()));
        dto.setJbr(String.valueOf(loginUser.getId()));
        dto.setYybm(String.valueOf(loginUser.getVisitDeptId()));
        dto.setFb(String.valueOf(loginUser.getVisitCompanyId()));
        dto.setSqsj(sdf.format(new Date()));
        dto.setYyqx("检测报告用印");
        dto.setYysy("检测报告用印");
        dto.setYysx("检测报告用印");
        dto.setXyywjUrl(docFile.getUrl());
        dto.setYwxtdjbh(sequenceUtil.genCode(sequenceKey));
        return iWorkIntegrationApi.createWorkflow(dto);
    }

    /*
     * 生成新版pdf文件
     * 在reportDocumentFile创建新pdf文件
     * */
    public ReportDocumentFileDO generatePdf(ReportDocumentMainDO mainDO) throws IOException {
        String pageFlag = "1";  //分页处理
        Long typeId = mainDO.getReportDocumentTypeId();
        ReportDocumentTypeDO typeDO = reportDocumentTypeService.getReportDocumentType(typeId);
        DataTemplateDO templateDO = dataTemplateService.getDataTemplate(mainDO.getDataTemplateId());
        CommonResult<JSONArray> result = reportDocumentDataService.assembleDynamicData(mainDO, typeDO, pageFlag);
        JSONArray data = result.getData();
        String templateContent = templateDO.getFormContent();
        JSONObject bodyJson = new JSONObject();
        bodyJson.put("Template", templateContent);
        bodyJson.put("Data", data.toJSONString());
        String bodyStr = bodyJson.toJSONString();
        log.info("html2pdf body: " + bodyStr);
        log.info("html2pdf--start at {}", LocalDateTime.now());
        HttpResponse response = HttpUtil.createPost(html2pdfAddr)
                .body(bodyStr)
                .timeout(15000)
                .execute();
        log.info("html2pdf--end at {}", LocalDateTime.now());
        InputStream inputStream = response.bodyStream(); // 关键：返回原始 InputStream

        //尝试从响应头中提取文件名
        String documentCode = mainDO.getDocumentCode();
        if(documentCode == null) documentCode = "";
        String filename = documentCode + "检测报告.pdf";
        byte[] fileBytes = IOUtils.toByteArray(inputStream);

        //上传到文件服务
        FileCreateReqDTO fileCreateReqDTO = new FileCreateReqDTO();
        fileCreateReqDTO.setName(filename);
        fileCreateReqDTO.setDirectory(null);
        fileCreateReqDTO.setType(null);
        fileCreateReqDTO.setContent(fileBytes);
        CommonResult<FileRespDTO> fileResult = fileApi.createFileWithReturn(fileCreateReqDTO);
        if (fileResult == null || !fileResult.isSuccess() || fileResult.getData() == null) {
            throw new ServiceException(REPORT_DOCUMENT_FILE_NOT_EXISTS.getCode(), "通过文件服务创建附件失败: " + Optional.ofNullable(fileResult).map(CommonResult::getMsg).orElse("未知错误"));
        }
        FileRespDTO fileRespDTO = fileResult.getData();
        //写入ReportDocumentFile
        ReportDocumentFileSaveReqVO fileSaveReqVO = new ReportDocumentFileSaveReqVO();
        fileSaveReqVO.setMainId(mainDO.getId());
        fileSaveReqVO.setFileId(fileRespDTO.getId());
        fileSaveReqVO.setName(filename);
        fileSaveReqVO.setPath(fileRespDTO.getDirectory());
        fileSaveReqVO.setUrl(fileRespDTO.getUrl());
        fileSaveReqVO.setVersion(mainDO.getDocumentVersion());
        reportDocumentFileService.createReportDocumentFile(fileSaveReqVO);
        return BeanUtils.toBean(fileRespDTO, ReportDocumentFileDO.class);
    }
}
