package com.testor.module.wf.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.core.util.StrUtil;
import com.testor.common.core.exception.ServiceException;
import com.testor.common.core.utils.StringUtils;
import com.testor.module.hazard.model.dto.TaskInfoDTO;
import com.testor.module.hazard.model.enums.WorkPlanStatusEnum;
import com.testor.module.wf.dao.RuTaskDao;
import com.testor.module.wf.service.RuTaskService;
import com.testor.module.wf.utils.CastUtils;
import com.testor.module.wf.utils.ExpressionCmd;
import com.testor.module.wf.utils.VariableUtils;
import com.testor.module.wf.vo.ProcessDefListRequestVO;
import com.tongtech.tfw.backend.common.biz.constants.BizConstants;
import com.tongtech.tfw.backend.common.biz.models.BaseResponseList;
import com.tongtech.tfw.backend.common.context.ContextUtils;
import com.tongtech.tfw.backend.core.helper.StringHelper;
import com.tongtech.tfw.backend.core.helper.bean.BeanHelper;
import com.tongtech.tfw.workflow.apis.definition.model.domain.ActReDeployment;
import com.tongtech.tfw.workflow.apis.definition.model.domain.ActReProcdef;
import com.tongtech.tfw.workflow.apis.definition.model.dto.ProcessDefListResponse;
import com.tongtech.tfw.workflow.apis.definition.service.ActReDeploymentService;
import com.tongtech.tfw.workflow.apis.definition.service.ActReProcdefService;
import com.tongtech.tfw.workflow.apis.task.model.dto.HisTask;
import com.tongtech.tfw.workflow.apis.task.model.dto.HisTaskListRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.flowable.bpmn.model.*;
import org.flowable.bpmn.model.Process;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.*;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.task.Comment;
import org.flowable.identitylink.api.IdentityLink;
import org.flowable.idm.api.Group;
import org.flowable.idm.api.User;
import org.flowable.task.api.Task;
import com.tongtech.tfw.workflow.apis.task.model.dto.*;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@Service
public class RuTaskServiceImpl implements RuTaskService {

    @Autowired
    private RuTaskDao ruTaskMapper;
    @Autowired
    private ActReProcdefService actReProcdefService;

    @Autowired
    private ActReDeploymentService actReDeploymentService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private ProcessEngine processEngine;
    @Autowired
    private TaskService taskService;
    @Autowired
    private IdentityService identityService;

    @Override
    public HisTask getHisTask(HisTaskListRequest hisTaskListRequest) {
        HisTask hisTask = ruTaskMapper.getHisTask(hisTaskListRequest);
        //可能是查的子流程但传的流程id是主流程的
        if(null == hisTask){
            if(!StringUtils.isEmpty(hisTaskListRequest.getTaskId())){
                hisTask = ruTaskMapper.getTaskId(hisTaskListRequest.getTaskId());
            }
        }
        return hisTask;
    }

    /**
     * 获取流程定义列表
     * @param param 请求参数
     * @return 流程定义响应列表
     */
    @Override
    public BaseResponseList<ProcessDefListResponse> getProcessDefList(ProcessDefListRequestVO param) {
        // 页码和每页限制，默认值通过常量
        Long page = StringHelper.isEmpty(param.getPage()) ? BizConstants.PAGE : Long.valueOf(param.getPage());
        Long limit = StringHelper.isEmpty(param.getLimit()) ? BizConstants.LIMIT : Long.valueOf(param.getLimit());
        Page<ActReProcdef> resultPage = new Page<>(page, limit);
        QueryWrapper<ActReProcdef> queryWrapper = new QueryWrapper<>();

        if (StringHelper.isNotEmpty(param.getName())) {
            queryWrapper.like("NAME_", param.getName());
        }
        if (StringHelper.isNotEmpty(param.getKey())) {
            queryWrapper.like("KEY_", param.getKey());
        }
        if (StringHelper.isNotEmpty(param.getCategory())) {
            queryWrapper.eq("CATEGORY_", param.getCategory());
        }
        if (StringHelper.isNotEmpty(param.getTabType())) {
            //如果是待办
            if ("1".equals(param.getTabType())) {
                if (StringHelper.isNotBlank(param.getType())) {
                    if ("PC".equals(param.getType())) {
                        queryWrapper.ne("NAME_", "危险作业");
                    }
                }
            }
        }

        // 获取分页查询结果
        Page<ActReProcdef> actReProcdefIPage = actReProcdefService.page(resultPage, queryWrapper);

        // 获取查询结果列表
        List<ActReProcdef> queryList = actReProcdefIPage.getRecords();

        // 使用Map存储每个key对应的最大版本号流程定义
        Map<String, ActReProcdef> maxVersionProcessDefs = new HashMap<>();

        for (ActReProcdef actReProcdef : queryList) {
            String key = actReProcdef.getKey();
            Long version = actReProcdef.getVersion();
            // 如果当前key还未出现，或者发现了更大的版本号，更新该key对应的最大版本号流程定义
            if (!maxVersionProcessDefs.containsKey(key) || version > maxVersionProcessDefs.get(key).getVersion()) {
                maxVersionProcessDefs.put(key, actReProcdef);
            }
        }

        // 获取所有最大版本号的流程定义
        List<ActReProcdef> maxVersionList = new ArrayList<>(maxVersionProcessDefs.values());

        // 按name分组，并合并key
        Map<String, StringBuilder> nameKeyMap = new HashMap<>();

        for (ActReProcdef actReProcdef : maxVersionList) {
            String name = actReProcdef.getName();
            String key = actReProcdef.getKey();

            // 如果该name已经存在，则将key拼接到已有的StringBuilder中
            nameKeyMap.computeIfAbsent(name, k -> new StringBuilder()).append(key).append(",");
        }

        // 转换为目标格式，并设置合并后的key
        List<ProcessDefListResponse> resultList = nameKeyMap.entrySet().stream().map(entry -> {
            String name = entry.getKey();
            String keys = entry.getValue().toString();

            // 去掉最后一个逗号
            if (keys.endsWith(",")) {
                keys = keys.substring(0, keys.length() - 1);
            }

            // 获取其中一个最大版本号的流程定义，用于获取部署信息等
            ActReProcdef actReProcdef = maxVersionProcessDefs.values().stream()
                    .filter(p -> p.getName().equals(name))
                    .findFirst()
                    .orElse(null);

            // 创建响应对象
            ProcessDefListResponse processDefListResponse = BeanHelper.beanToBean(actReProcdef, ProcessDefListResponse.class);
            processDefListResponse.setName(name);
            processDefListResponse.setKey(keys); // 设置合并后的key

            if (actReProcdef != null && StringHelper.isNotEmpty(actReProcdef.getDeploymentId())) {
                ActReDeployment actReDeployment = actReDeploymentService.getById(actReProcdef.getDeploymentId());
                if (actReDeployment != null) {
                    processDefListResponse.setDeployTime(actReDeployment.getDeployTime());
                    processDefListResponse.setCategory(actReDeployment.getCategory());
                }
            }

            // 设置是否暂停
            processDefListResponse.setSuspended(actReProcdef != null && actReProcdef.getSuspensionState() != 1L);

            return processDefListResponse;
        }).collect(Collectors.toList());

        if ("2".equals(param.getTabType())){
            ProcessDefListResponse defListResponse = new ProcessDefListResponse();
            defListResponse.setKey("aptitude");
            defListResponse.setName("证件过期提醒");
            resultList.add(defListResponse);
        }

        // 构建返回的响应对象
        BaseResponseList<ProcessDefListResponse> responseList = new BaseResponseList<>();
        responseList.setData(resultList);
        return responseList;
    }

    public List<Map> countToDo(String userId, String orgId) {
        return StrUtil.isBlank(userId) ? null : this.ruTaskMapper.countToDo(userId, orgId);
    }

    @Override
    public IPage<TodoTask> selectToDoList(IPage<TodoTask> page, TodoTaskSqlParam todoTaskSqlParam) {
        return this.ruTaskMapper.selectToDoList(page, todoTaskSqlParam);
    }

    @Override
    public IPage<HisTask> selectHisTaskList(IPage<HisTask> page, HisTaskSqlParam hisTaskSqlParam) {
        return this.ruTaskMapper.selectHisTaskList(page, hisTaskSqlParam);
    }

    @Override
    public boolean getElValue(String exp, Map<String, Object> variableMap) {
        return this.getElValue(null, exp, variableMap);
    }

    @Override
    public boolean getElValue(String processInstanceId, String exp, Map<String, Object> variableMap) {
        if (StringUtils.isBlank(exp)) {
            return true;
        }

        ManagementService managementService = processEngine.getManagementService();
        boolean flag = managementService.executeCommand(new ExpressionCmd(processEngine, processInstanceId, exp, variableMap));

        //删除垃圾数据
        this.deleteException();
        return flag;
    }

    public void deleteException(){
        //删除垃圾数据
        ruTaskMapper.deleteRuVariableException();
        ruTaskMapper.deleteHiVariableException();
    }




    @Override
    public List<String> getNextNameTasks(String taskId, Map<String, Object> variables) {
        List<String> nextFlowNodeNames = new ArrayList<>();
        try {
            if (StringUtils.isBlank(taskId)) {
                return new ArrayList<>();
            }
            Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
            log.info("RuTaskServiceImpl-getNextNameTasks-当前任务task,参数：taskId={}，variables={},task={}" , taskId , variables, task.getName()+task.getId());
            if (null == task) {
                log.error("RuTaskServiceImpl-getNextNameTasks-当前任务不存在,参数：taskId={}，variables={}" , taskId , variables);
                return new ArrayList<>();
            }
            Map<String, Object> variableMap = taskService.getVariables(task.getId());
            variableMap.putAll(variables);
            List<FlowElement> nextFlowNodes = this.getNextFlowNodes(task, variableMap);
            log.info("RuTaskServiceImpl-getNextNameTasks-当前任务nextFlowNodes,参数：task={}，variableMap={},nextFlowNodes={}" ,
                    task.getName()+task.getId() , variableMap, JSON.toJSONString(nextFlowNodes));
            for (FlowElement nextFlowNode : nextFlowNodes) {
                nextFlowNodeNames.add(nextFlowNode.getName());
            }
        }catch (Exception e) {
            e.printStackTrace();
            log.error("RuTaskServiceImpl-getNextNameTasks-获取下一任务节点集合异常", e);
        }
        return nextFlowNodeNames;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void stopProcess(String processInstanceId) {
        String loginUserId = ContextUtils.getLoginUserId();

        List<Task> taskList = taskService.createTaskQuery().processInstanceId(processInstanceId).list();
        if (CollectionUtils.isEmpty(taskList)) {
           log.error("流程未启动或已执行完成，取消申请失败");
           return;
        }

        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(processInstanceId).singleResult();

        BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
        if (Objects.nonNull(bpmnModel)) {
            Process process = bpmnModel.getMainProcess();
            List<EndEvent> endNodes = process.findFlowElementsOfType(EndEvent.class, false);
            if (CollectionUtils.isNotEmpty(endNodes)) {
                Authentication.setAuthenticatedUserId(loginUserId);
                runtimeService.setVariable(processInstance.getId(), "processStatus", WorkPlanStatusEnum.CANCELED.getValue());
                for (Task task : taskList) {
                    taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), WorkPlanStatusEnum.CANCELED.getValue() , "取消流程");
                }
                // 获取当前流程最后一个节点
                String endId = endNodes.get(0).getId();
                List<Execution> executions = runtimeService.createExecutionQuery()
                        .parentId(processInstance.getProcessInstanceId()).list();
                List<String> executionIds = new ArrayList<>();
                executions.forEach(execution -> executionIds.add(execution.getId()));
                // 变更流程为已结束状态
                runtimeService.createChangeActivityStateBuilder()
                        .moveExecutionsToSingleActivityId(executionIds, endId).changeState();
            }
        }

    }

    @Override
    public List<TaskInfoDTO> getAllTaskApprovers(String processInstanceId) {
        List<TaskInfoDTO> result = new ArrayList<>();

        // 1. 获取已完成的任务（历史记录）
        List<HistoricTaskInstance> historicTasks = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(processInstanceId)
                .finished() // 只查询已完成的任务
                .orderByHistoricTaskInstanceEndTime().asc()
                .list();

        // 2. 获取当前可处理的任务（运行时任务）
        List<Task> activeTasks  = taskService.createTaskQuery()
                .processInstanceId(processInstanceId)
                .list();

        // 3. 合并结果
        result.addAll(convertHistoricTasks(historicTasks));
        result.addAll(convertActiveTasks(activeTasks));

        return result;
    }


    private List<TaskInfoDTO> convertHistoricTasks(List<HistoricTaskInstance> tasks) {
        return tasks.stream().map(task -> {
            TaskInfoDTO dto = new TaskInfoDTO();
            dto.setTaskId(task.getId());
            dto.setTaskName(task.getName());
            dto.setAssignee(getUserDisplayName(task.getAssignee()));
            dto.setStartTime(task.getStartTime());
            dto.setEndTime(task.getEndTime());
            getStatus(dto, task.getId());
            dto.setVars(getMap(task.getId()));
            // 获取审批意见
            List<Comment> comments = taskService.getTaskComments(task.getId(),"6");
            if (!comments.isEmpty()) {
                dto.setStatus("已取消");
                dto.setComment(comments.get(0).getFullMessage());
            }
            return dto;
        }).collect(Collectors.toList());
    }

    private List<TaskInfoDTO> convertActiveTasks(List<Task> tasks) {
        return tasks.stream().map(task -> {
            TaskInfoDTO dto = new TaskInfoDTO();
            dto.setTaskId(task.getId());
            dto.setTaskName(task.getName());
            dto.setStatus("审批中");
            dto.setAssignee(getUserDisplayName(task.getAssignee()));
            dto.setStartTime(task.getCreateTime());

            // 获取当前任务的候选人和候选组
            if (StringUtils.isBlank(task.getAssignee())) {
                List<IdentityLink> identityLinks = taskService.getIdentityLinksForTask(task.getId());
                List<String> candidateUsers = new ArrayList<>();
                List<String> candidateGroups = new ArrayList<>();

                for (IdentityLink link : identityLinks) {
                    if (link.getUserId() != null) {
                        String userDisplayName = getUserDisplayName(link.getUserId());
                        if (StringUtils.isNotBlank(userDisplayName)) {
                            candidateUsers.add(userDisplayName);
                        }
                    }
                    if (link.getGroupId() != null && link.getGroupId().contains("-")) {
                        candidateGroups.add(getGroupDisplayName(link.getGroupId()));
                    }
                }
                dto.setCandidateUsers(candidateUsers);
                dto.setCandidateGroups(candidateGroups);
            }

            getStatus(dto, task.getId());
            //Map<String, Object> map = getMap(task.getId());
            //dto.setMap(map);

            return dto;
        }).collect(Collectors.toList());
    }

    private void getStatus(TaskInfoDTO dto, String id) {
        Map<String, Object> map = getMap(id);
        Object rejected = null;
        if (map != null) {
            rejected = map.get("rejected");
            if (rejected != null) {
                String rejectedString = rejected.toString();
                if ("0".equals(rejectedString)){
                    dto.setStatus("通过");
                }else {
                    dto.setStatus("驳回");
                }
            }else {
                dto.setStatus("通过");
            }
        }else {
            dto.setStatus("审批中");
        }
    }

    private String getUserDisplayName(String userId) {
        if (userId == null) return null;
        User user = identityService.createUserQuery().userId(userId).singleResult();
        return user != null ? user.getFirstName() + String.format("(%s)",user.getLastName()) : userId;
    }

    private String getGroupDisplayName(String groupId) {
        Group group = identityService.createGroupQuery().groupId(groupId).singleResult();
        return group != null ? group.getName() : groupId;
    }

    private Map<String,Object> getMap(String taskId) {
        if (StringHelper.isNotBlank(taskId)) {
            try {
                List<HistoricVariableInstance> taskVarList = this.historyService.createHistoricVariableInstanceQuery().taskId(taskId).list();
                if (!taskVarList.isEmpty()) {
                    return taskVarList.stream().collect(Collectors.toMap(HistoricVariableInstance::getVariableName, (ex) -> ex.getValue() == null ? "" : ex.getValue(), (k1, k2) -> k1));
                }
            } catch (Exception e) {
                log.error(e.toString());
            }
        }
        return null;
    }


    /**
     * 获取下一任务节点集合
     *
     * @param task 当前任务
     * @param variables 参数
     * @return 下一任务节点集合
     */
    public List<FlowElement> getNextFlowNodes(Task task, Map<String, Object> variables) {
        if (null == task) {
            return new ArrayList<>();
        }

        // 当前审批节点
        String currentActivityId = task.getTaskDefinitionKey(); //当前环节id
        BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());

        //复制一份
        List<FlowElement> flowElements = new ArrayList<>(bpmnModel.getMainProcess().getFlowElements());
        List<FlowElement> nextElements = new ArrayList<>();

        FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(currentActivityId);
        // 输出连线
        List<SequenceFlow> outFlows = flowNode.getOutgoingFlows();

        FlowElement targetElement;
        List<SequenceFlow> sequenceFlows = this.getSequenceFlows(variables, outFlows);
        for (SequenceFlow sequenceFlow : sequenceFlows) {
            targetElement = this.getFlowElement(flowElements, sequenceFlow.getTargetRef());
            this.getNextElementList(nextElements, flowElements, targetElement, variables);
        }
        return nextElements;
    }



    public boolean getSkipElValue(String exp, Map<String, Object> variableMap) {
        //表达式为空，节点不跳过
        if (StringUtils.isBlank(exp)) {
            return false;
        }

        //skip：true 跳过节点/false 不跳过节点
        boolean skip = false;
        Map<String, Object> variables = new HashMap<>(variableMap);
        Object flowableSkipExpressionEnabled = variables.get("_FLOWABLE_SKIP_EXPRESSION_ENABLED");
        //流程参数含有_FLOWABLE_SKIP_EXPRESSION_ENABLED，且为true时，表示FLOWABLE跳过表达式已启用
        if (null != flowableSkipExpressionEnabled && "true".equals(flowableSkipExpressionEnabled.toString())) {
            //返回true，表示跳过该任务节点；
            ManagementService managementService = processEngine.getManagementService();
            skip = managementService.executeCommand(new ExpressionCmd(exp, variables));

            //删除垃圾数据
            this.deleteException();
        }

        return skip;
    }

    /**
     * 任务节点
     */
    private void dueUserTaskElement(List<FlowElement> nextElements, Collection<FlowElement> flowElements, FlowElement curFlowElement, Map<String, Object> variableMap) {
        UserTask userTask = (UserTask) curFlowElement;
        //skip：true 跳过节点/false 不跳过节点
        boolean skip = this.getSkipElValue(userTask.getSkipExpression(), variableMap);
        if (!skip) {
            //不跳过节点，
            nextElements.add(curFlowElement);
        } else {

            //跳过节点，查询下一节点
            List<SequenceFlow> outgoingFlows = userTask.getOutgoingFlows();
            if (outgoingFlows.size() > 0) {
                String targetRef = outgoingFlows.get(0).getTargetRef();
                if (outgoingFlows.size() > 1) {
                    // 找到表达式成立的sequenceFlow
                    SequenceFlow sequenceFlow = getSequenceFlow(variableMap, outgoingFlows);
                    targetRef = sequenceFlow.getTargetRef();
                }
                // 根据ID找到FlowElement
                FlowElement targetElement = this.getFlowElement(flowElements, targetRef);
                this.getNextElementList(nextElements, flowElements, targetElement, variableMap);
            }
        }
    }

    /**
     * 排他网关
     */
    private void dueExclusiveGateway(List<FlowElement> nextElements, Collection<FlowElement> flowElements, FlowElement curFlowElement, Map<String, Object> variableMap) {
        // 获取符合条件的sequenceFlow的目标FlowElement
        List<SequenceFlow> exclusiveGatewayOutgoingFlows = ((ExclusiveGateway) curFlowElement).getOutgoingFlows();
        flowElements.remove(curFlowElement);
        // 找到表达式成立的sequenceFlow
        SequenceFlow sequenceFlow = this.getSequenceFlow(variableMap, exclusiveGatewayOutgoingFlows);
        // 根据ID找到FlowElement
        FlowElement targetElement = this.getFlowElement(flowElements, sequenceFlow.getTargetRef());
        this.getNextElementList(nextElements, flowElements, targetElement, variableMap);
    }

    /**
     * 并行网关
     */
    private void dueParallelGateway(List<FlowElement> nextElements, Collection<FlowElement> flowElements, FlowElement curFlowElement, Map<String, Object> variableMap) {
        FlowElement targetElement;
        List<SequenceFlow> parallelGatewayOutgoingFlows = ((ParallelGateway) curFlowElement).getOutgoingFlows();
        for (SequenceFlow sequenceFlow : parallelGatewayOutgoingFlows) {
            targetElement = this.getFlowElement(flowElements, sequenceFlow.getTargetRef());
            this.getNextElementList(nextElements, flowElements, targetElement, variableMap);
        }
    }

    /**
     * 包含网关
     */
    private void dueInclusiveGateway(List<FlowElement> nextElements, Collection<FlowElement> flowElements, FlowElement curFlowElement, Map<String, Object> variableMap) {
        FlowElement targetElement;
        List<SequenceFlow> inclusiveGatewayOutgoingFlows = ((InclusiveGateway) curFlowElement).getOutgoingFlows();
        List<SequenceFlow> sequenceFlows = this.getSequenceFlows(variableMap, inclusiveGatewayOutgoingFlows);
        for (SequenceFlow sequenceFlow : sequenceFlows) {
            targetElement = this.getFlowElement(flowElements, sequenceFlow.getTargetRef());
            this.getNextElementList(nextElements, flowElements, targetElement, variableMap);
        }
    }

    /**
     * 获取下一环节任务节点集合
     */
    private void getNextElementList(List<FlowElement> nextElements, Collection<FlowElement> flowElements, FlowElement curFlowElement, Map<String, Object> variableMap) {
        if (null == curFlowElement) {
            return;
        }

        // 任务节点
        if (curFlowElement instanceof UserTask) {
            this.dueUserTaskElement(nextElements, flowElements, curFlowElement, variableMap);
            return;
        }
        // 排他网关
        if (curFlowElement instanceof ExclusiveGateway) {
            this.dueExclusiveGateway(nextElements, flowElements, curFlowElement, variableMap);
            return;
        }
        // 并行网关
        if (curFlowElement instanceof ParallelGateway) {
            this.dueParallelGateway(nextElements, flowElements, curFlowElement, variableMap);
        }
        // 包含网关
        if (curFlowElement instanceof InclusiveGateway) {
            this.dueInclusiveGateway(nextElements, flowElements, curFlowElement, variableMap);
        }
        // 事件网关
        if (curFlowElement instanceof EventGateway) {
            this.dueEventGateway(nextElements, flowElements, curFlowElement, variableMap);
        }
    }

    /**
     * 事件网关
     */
    private void dueEventGateway(List<FlowElement> nextElements, Collection<FlowElement> flowElements, FlowElement curFlowElement, Map<String, Object> variableMap) {
    }

    /**
     * 根据ID找到FlowElement
     * @param flowElements 流程节点集合
     * @param targetRef id
     * @return FlowElement
     */
    private FlowElement getFlowElement(Collection<FlowElement> flowElements, String targetRef) {
        return flowElements.stream().filter(flowElement -> targetRef.equals(flowElement.getId())).findFirst().orElse(null);
    }

    /**
     * 根据传入的变量，计算出表达式成立的那一条SequenceFlow
     *
     * @param variableMap   变量map
     * @param outgoingFlows 输出流
     * @return SequenceFlow连线
     */
    private SequenceFlow getSequenceFlow(Map<String, Object> variableMap, List<SequenceFlow> outgoingFlows) {
        List<SequenceFlow> sequenceFlows = this.getSequenceFlows(variableMap, outgoingFlows);
        if (null != sequenceFlows && sequenceFlows.size() > 0) {
            return sequenceFlows.get(0);
        }

        return outgoingFlows.get(0);
    }

    /**
     * 根据传入的变量，计算出表达式成立的SequenceFlow连线集合
     *
     * @param variableMap   变量map
     * @param outgoingFlows 输出流
     * @return SequenceFlow连线集合
     */
    private List<SequenceFlow> getSequenceFlows(Map<String, Object> variableMap, List<SequenceFlow> outgoingFlows) {
        List<SequenceFlow> sequenceFlows;
        sequenceFlows = outgoingFlows.stream().filter(item -> {
            try {
                return this.getElValue(item.getConditionExpression(), variableMap);
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }).collect(Collectors.toList());
        return sequenceFlows;
    }

}
