package cn.axzo.workflow.server.controller.listener.process;

import cn.axzo.workflow.common.enums.FileTypeEnum;
import cn.axzo.workflow.common.model.dto.SignFileDTO;
import cn.axzo.workflow.common.model.dto.VariableObjectDTO;
import cn.axzo.workflow.common.model.request.bpmn.BpmnSignConf;
import cn.axzo.workflow.core.common.context.ProcessOperationContext;
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
import cn.axzo.workflow.core.listener.AbstractBpmnEventListener;
import cn.axzo.workflow.core.listener.BpmnProcessEventListener;
import cn.axzo.workflow.core.repository.entity.ExtAxDocContent;
import cn.axzo.workflow.core.repository.entity.ExtAxProcessSign;
import cn.axzo.workflow.core.service.ExtAxDocContentService;
import cn.axzo.workflow.core.service.ExtAxModelDocService;
import cn.axzo.workflow.core.service.ExtAxProcessSignService;
import cn.axzo.workflow.server.common.util.WpsUtil;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.Process;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
import org.flowable.engine.HistoryService;
import org.flowable.engine.ProcessEngineConfiguration;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.ProcessDefinitionUtil;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Scope;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 签署业务，审批完成后，进行文件归档，并对所有工人发送业务待办
 *
 * @author wangli
 * @since 2025-04-01 17:58
 */
@Slf4j
@Component
@Scope("prototype")
@RefreshScope
public class FileArchiveProcessEventListener extends AbstractBpmnEventListener<ProcessOperationContext> implements BpmnProcessEventListener, Ordered {
    @Resource
    private HistoryService historyService;
    @Resource
    private ExtAxProcessSignService extAxProcessSignService;
    @Resource
    private ExtAxModelDocService extAxModelDocService;
    @Resource
    private ExtAxDocContentService extAxDocContentService;
    @Resource
    private WpsUtil wpsUtil;


    @Override
    public void onCompleted(FlowableEngineEntityEvent event) {
        Process mainProcess = ProcessDefinitionUtil.getBpmnModel(event.getProcessDefinitionId()).getMainProcess();
        Optional<BpmnSignConf> signConfig = BpmnMetaParserHelper.getSignConfig(mainProcess);
        if (!signConfig.isPresent() || Objects.isNull(signConfig.get().getSignType())) {
            // 未配置签批设置
            return;
        }

        String processInstanceId = event.getProcessInstanceId();
        HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(processInstanceId).includeProcessVariables().singleResult();

        // 文件归档，将审批过程中产生的数据全部替换文档模板变量
        archiveFinalDocs(instance);
    }

    private void archiveFinalDocs(HistoricProcessInstance instance) {
        ProcessEngineConfigurationImpl processEngineConfiguration = (ProcessEngineConfigurationImpl) getEngineConfiguration();
        ExtAxProcessSign processSign = extAxProcessSignService.findByProcessInstanceId(instance.getId());
        List<VariableObjectDTO> wpsReplaceVariables = wpsUtil.getWpsReplaceVariables(processEngineConfiguration, instance.getId());
        processSign.getFileArchive().stream().filter(i -> Objects.equals(i.getFileType(), FileTypeEnum.WORD)
                        || Objects.equals(i.getFileType(), FileTypeEnum.EXCEL))
                .forEach(docBaseVO -> {
                    String newFileKey = wpsUtil.wpsFileVariableReplace(wpsReplaceVariables, null, docBaseVO.getFileKey(), docBaseVO.getTemplateName() + docBaseVO.getFileType().getSuffix());
                    docBaseVO.setFileKey(newFileKey);
                });
        // 删除非 WPS 的临时文档
        removeTempFile(processSign);
        // 暂时不删除 WPS 的临时文档
//        removeTempWpsFile(processSign);
        extAxProcessSignService.updateById(processSign);
    }

    private void removeTempWpsFile(ExtAxProcessSign processSign) {
        processSign.getDocTemplate().stream()
                .filter(i -> Objects.equals(i.getFileType(), FileTypeEnum.WORD) || i.getFileType().equals(FileTypeEnum.EXCEL))
                .forEach(docBaseVO -> {
                    wpsUtil.deleteWpsFile(docBaseVO.getFileCode());
                });
    }

    private void removeTempFile(ExtAxProcessSign processSign) {
        List<Long> deleteTempFileIds = processSign.getDocTemplate().stream().filter(i -> Objects.equals(i.getFileType(), FileTypeEnum.HIPRINT)).map(SignFileDTO::getFileCode).map(Long::parseLong).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(deleteTempFileIds)) {
            return;
        }
        List<ExtAxDocContent> contents = extAxDocContentService.getByIds(deleteTempFileIds);
        extAxModelDocService.batchDeleteDoc(contents.stream().map(ExtAxDocContent::getFileId).collect(Collectors.toList()));
    }

    private ProcessEngineConfiguration getEngineConfiguration() {
        return getContext().getProcessEngineConfiguration(CommandContextUtil::getProcessEngineConfiguration);
    }

    @Override
    public int getOrder() {
        return Integer.MIN_VALUE + 3;
    }
}
