package cn.fateverse.workflow.process;

import cn.fateverse.workflow.entity.HistoricalOperation;
import cn.fateverse.workflow.entity.bpmn.CommentInfo;
import cn.fateverse.workflow.entity.bpmn.UserInfo;
import cn.fateverse.workflow.entity.vo.HistoricalOperationVo;
import cn.fateverse.workflow.mapper.HistoricalOperationMapper;
import com.alibaba.fastjson2.JSON;
import org.flowable.bpmn.model.*;
import org.flowable.bpmn.model.Process;
import org.flowable.engine.RepositoryService;
import org.jetbrains.annotations.NotNull;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 流程服务工具类
 *
 * @author Clay
 * @date 2023/1/24
 */
public class ProcessServiceUtils {

    /**
     * 获取操作历史数据
     *
     * @param processInstanceId 流程实例id
     * @return 返回的vo对象
     */
    public static List<HistoricalOperationVo> getHistoricalOperations(String processInstanceId, HistoricalOperationMapper operationMapper) {
        return getHistoricalOperations(processInstanceId, operationMapper, 0);
    }

    /**
     * 获取到操作记录
     *
     * @param processInstanceId 部署流程id
     * @param operationMapper   操作映射
     * @param mark              标记
     * @return 返回的vo对象
     */
    public static List<HistoricalOperationVo> getHistoricalOperations(String processInstanceId, HistoricalOperationMapper operationMapper, Integer mark) {
        List<HistoricalOperation> operationList = operationMapper.selectListByProcessInstanceId(processInstanceId, mark);
        return getHistoricalOperationVoList(operationList);
    }

    /**
     * HistoricalOperation 转换为 Vo对象
     *
     * @param operationList 操作历史
     * @return 返回的vo对象
     */
    @NotNull
    public static List<HistoricalOperationVo> getHistoricalOperationVoList(List<HistoricalOperation> operationList) {
        return operationList.stream().map(operation -> {
            HistoricalOperationVo vo = HistoricalOperationVo.builder()
                    .taskId(operation.getTaskId())
                    .processInstanceId(operation.getProcessInstanceId())
                    .operationName(operation.getOperationName())
                    .operation(operation.getOperation())
                    .finishTime(operation.getFinishTime())
                    .nodeId(operation.getNodeId())
                    .state(operation.getState())
                    .mark(operation.getMark())
                    .startTime(new Date(operation.getStartTime()))
                    .build();
            if (null != operation.getMessage()) {
                CommentInfo comment = JSON.parseObject(operation.getMessage(), CommentInfo.class);
                vo.setComment(comment);
            }
            if (null != operation.getUserInfo()) {
                List<UserInfo> userInfo = JSON.parseArray(operation.getUserInfo(), UserInfo.class);
                vo.setUserInfo(userInfo);
            }
            return vo;
        }).collect(Collectors.toList());
    }


    /**
     * 获取到bpmn的数据
     *
     * @param repositoryService   引擎获取模型对象
     * @param processDefinitionId 流程id
     * @param key                 参数关键词
     * @return 参数值
     */
    public static String getBpmnValue(RepositoryService repositoryService, String processDefinitionId, String key) {
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        Process process = bpmnModel.getProcesses().get(0);
        ExtensionAttribute attribute = process.getAttributes().get(key).get(0);
        return attribute.getValue();
    }

    /**
     * 获取到bpmn的数据
     *
     * @param repositoryService   引擎获取模型对象
     * @param processDefinitionId 流程id
     * @return 参数值
     */
    public static Map<String, String> getBpmnValueAttribute(RepositoryService repositoryService, String processDefinitionId) {
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        Process process = bpmnModel.getProcesses().get(0);
        return getBpmnValueAttribute(process);
    }

    /**
     * 获取到bpmn的数据
     *
     * @param process 流程信息
     * @return 参数
     */
    public static Map<String, String> getBpmnValueAttribute(Process process) {
        Map<String, List<ExtensionAttribute>> attributes = process.getAttributes();
        return attributes.keySet().stream().map(key -> attributes.get(key).get(0)).collect(Collectors.toMap(ExtensionAttribute::getName, ExtensionAttribute::getValue));
    }


}
