package org.springblade.flow.engine.custom.helper;

import static org.springblade.flow.base.util.BpmnModelUtils.getAttributeValueByTaskDefinitionKey;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.APPLY_USER_ID;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.FLOW_ENGINE_ID;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springblade.flow.engine.assembly.UserTaskExPropertyDTO;
import org.springblade.flow.engine.assembly.prop.UserTaskAdvancedSettingDTO;
import org.springblade.flow.engine.assembly.prop.UserTaskBasicPropDTO;
import org.springblade.flow.engine.assembly.prop.UserTaskNodeEventDTO;
import org.springblade.flow.engine.custom.constants.BasicActivitiConstants;
import org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants;
import org.springblade.flow.engine.custom.variables.entity.FormDataInfo;
import org.springblade.flow.engine.dto.AvailableFlowDelegateDTO;
import org.springblade.flow.engine.enums.FlowMessageEnum;
import org.springblade.flow.engine.enums.FlowRecordEnum;
import org.springblade.flow.engine.enums.FlowTaskOperatorEnum;
import org.springblade.flow.engine.service.FlowDelegateService;
import org.springblade.flow.message.enums.MessageTypeEnum;
import org.springblade.flow.message.model.message.SentMessageForm;
import org.springblade.flow.message.util.SentMessageUtil;
import org.springblade.flow.permission.entity.OrganizeEntity;
import org.springblade.flow.permission.entity.UserEntity;
import org.springblade.flow.permission.entity.UserRelationEntity;
import org.springblade.flow.permission.service.OrganizeService;
import org.springblade.flow.permission.service.UserRelationService;
import org.springblade.flow.permission.service.User4FlowService;
import org.springblade.flow.util.JsonUtil;
import org.springblade.flow.util.JsonUtilEx;
import org.springblade.flow.util.StringUtil;
import org.springblade.flow.util.UserProvider;
import org.springblade.flow.util.wxutil.HttpUtil;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;

/**
 * @Author:LoveMyOrange
 * @Description: 用户节点找人的helper
 * @Date:Created in 2022/4/17 11:30
 */
@Component
public class UserTaskNodeHelper {

    @Resource
    private UserRelationService userRelationService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private FlowDelegateService flowDelegateService;
    @Resource
    private User4FlowService userService;
    @Resource
    private OrganizeService organizeService;
    @Resource
    private RepositoryService repositoryService;
    @Resource
    private HistoryService historyService;
    @Resource
    private SentMessageUtil sentMessageUtil;
    /**
     * 节点id
     **/
    private String taskNodeId = "taskNodeId";
    /**
     * 状态
     **/
    private String handleStatus = "handleStatus";
    /**
     * 任务id
     **/
    private String taskId = "taskId";

    /**
     *
     * @param userTaskExPropertyDTO 扩展属性
     * @param task
     * @param flowId
     * @return
     */
    public   List<String> getAssignUserList(UserTaskExPropertyDTO userTaskExPropertyDTO, Task task,String flowId) {
        String processDefinitionId = task.getProcessDefinitionId();
        String taskDefinitionKey = task.getTaskDefinitionKey();
        String processInstanceId = task.getProcessInstanceId();
        ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager();
        ExecutionEntity rootExecutionEntity = executionEntityManager.findById(processInstanceId);

        if(StringUtils.isBlank(flowId)){
            flowId = rootExecutionEntity.getVariable(FLOW_ENGINE_ID).toString();
        }

        String businessKey = rootExecutionEntity.getProcessInstanceBusinessKey();
        String applyUserId = (String) rootExecutionEntity.getVariable(BasicActivitiConstants.startEventInitiator);
        UserTaskBasicPropDTO userTaskBasicPropDTO = userTaskExPropertyDTO.getUserTaskBasicPropDTO();
        UserTaskAdvancedSettingDTO userTaskAdvancedSettingDTO = userTaskExPropertyDTO.getUserTaskAdvancedSettingDTO();
        String assigneeType = userTaskBasicPropDTO.getAssigneeType();
        List<String> approvers = userTaskBasicPropDTO.getApprovers();
        List<String> approverPos = userTaskBasicPropDTO.getApproverPos();
        List<String> approverRole = userTaskBasicPropDTO.getApproverRole();
        List<UserEntity> userList = userService.getList();
        List<String> userIds=new ArrayList<>();
        //指定人员
        if(FlowTaskOperatorEnum.Nominator.getCode().equals(assigneeType)){
            userIds.addAll(approvers);
            //角色和岗位下的用户  //乃至更多类型
            List<String> userRelationList=new ArrayList<>();
            if(ObjectUtil.isNotEmpty(approverPos) || ObjectUtil.isNotEmpty(approverRole)){
                userRelationList.addAll(approverPos);
                userRelationList.addAll(approverRole);
                List<UserRelationEntity> listByObjectIdAll = userRelationService.getListByObjectIdAll(userRelationList);
                List<String> userPosIds = listByObjectIdAll.stream().map(t -> t.getUserId()).collect(Collectors.toList());
                userIds.addAll(userPosIds);
            }
            //
            ArrayList<String> distinct = CollUtil.distinct(userIds);
            List<String> goOutList=new ArrayList<>();
            //判断这里面的人是不是有外出登记
            Iterator<String> iterator = distinct.iterator();
            while (iterator.hasNext()){
                String next = iterator.next();
                //外出登记判断
                AvailableFlowDelegateDTO availableFlowDelegateDTO = new AvailableFlowDelegateDTO();
                availableFlowDelegateDTO.setFlowId(flowId);
                availableFlowDelegateDTO.setCurrentUserId(next);
                String processData = flowDelegateService.getAvailableProcessData(availableFlowDelegateDTO);
                if(StringUtils.isNotBlank(processData)){
                    iterator.remove();
                    goOutList.add(processData);
                }
            }
            distinct.addAll(goOutList);
            return distinct;
        }
        //发起者主管
        else if(FlowTaskOperatorEnum.LaunchCharge.getCode().equals(assigneeType)){
            //实时查用户主管
            UserEntity info = userService.getInfo(applyUserId);
            if (info != null) {
                String userId = getManagerByLevel(info.getManagerId(), userTaskBasicPropDTO.getManagerLevel(), userList);
                if(StringUtils.isBlank(userId)){
                    return CollUtil.newArrayList();
                }
                else{
                    //外出登记判断
                    AvailableFlowDelegateDTO availableFlowDelegateDTO = new AvailableFlowDelegateDTO();
                    availableFlowDelegateDTO.setFlowId(flowId);
                    availableFlowDelegateDTO.setCurrentUserId(userId);
                    String processData = flowDelegateService.getAvailableProcessData(availableFlowDelegateDTO);
                    if(StringUtils.isBlank(processData)){
                        return CollUtil.newArrayList(userId);
                    }
                    return CollUtil.newArrayList(processData);
                }

            }

        }
        //发起人本人
        else if(FlowTaskOperatorEnum.InitiatorMe.getCode().equals(assigneeType)){
            //外出登记判断
            AvailableFlowDelegateDTO availableFlowDelegateDTO = new AvailableFlowDelegateDTO();
            availableFlowDelegateDTO.setFlowId(flowId);
            availableFlowDelegateDTO.setCurrentUserId(applyUserId);
            String trueAssignee = flowDelegateService.getAvailableProcessData(availableFlowDelegateDTO);
            if(StringUtils.isNotBlank(trueAssignee)){
                return CollUtil.newArrayList(trueAssignee);
            }
            else{
                return CollUtil.newArrayList(applyUserId);
            }
        }
        //部门主管
        else if(FlowTaskOperatorEnum.DepartmentCharge.getCode().equals(assigneeType)){
            UserEntity userEntity = userService.getInfo(applyUserId);
            OrganizeEntity organizeEntity = organizeService.getInfo(userEntity != null ? userEntity.getOrganizeId() : "");
            if (organizeEntity != null) {
               String userId = organizeEntity.getManager();
                //外出登记判断
                AvailableFlowDelegateDTO availableFlowDelegateDTO = new AvailableFlowDelegateDTO();
                availableFlowDelegateDTO.setFlowId(flowId);
                availableFlowDelegateDTO.setCurrentUserId(userId);
                String trueAssignee = flowDelegateService.getAvailableProcessData(availableFlowDelegateDTO);
                if(StringUtils.isNotBlank(trueAssignee)){
                    return CollUtil.newArrayList(trueAssignee);
                }
                else{
                    return CollUtil.newArrayList(userId);
                }
            }
        }
        //变量
        else if(FlowTaskOperatorEnum.Variate.getCode().equals(assigneeType)){
            String formField = userTaskBasicPropDTO.getFormField();

            FormDataInfo formDataInfo = runtimeService.getVariable(processInstanceId, GlobalProcessVariableConstants.FORM_INFO_JSON, FormDataInfo.class);
            Map<String, Object> map = JsonUtil.stringToMap(formDataInfo.getFormDataJson());
            Object data = map.get(formField);
            if (data != null) {
                List<String> handleId = Arrays.asList(String.valueOf(data).split(","));
                List<String> userAll = userList.stream().filter(t -> handleId.contains(t.getId())).map(t -> t.getId()).collect(Collectors.toList());
                return CollUtil.newArrayList(userAll);
            }
            else{
                return CollUtil.newArrayList();
            }
        }
        //环节
        else if(FlowTaskOperatorEnum.Tache.getCode().equals(assigneeType)){
            //此有歧义 留给后续产品经理探讨
            String nodeId = userTaskBasicPropDTO.getNodeId();
            BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
            Process mainProcess = bpmnModel.getMainProcess();
            UserTask targetNode = (UserTask) bpmnModel.getFlowElement(nodeId);
            String property = getAttributeValueByTaskDefinitionKey(mainProcess, taskDefinitionKey, "userTask");
            UserTaskExPropertyDTO exPropertyDTO = JSONObject.parseObject(property, new TypeReference<UserTaskExPropertyDTO>() {
            });
            UserTaskBasicPropDTO nodeUserTaskBasicPropDTO = exPropertyDTO.getUserTaskBasicPropDTO();
            List<HistoricTaskInstance> taskInstances = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).finished().taskDefinitionKey(nodeId).orderByTaskCreateTime().desc().list();
            if(taskInstances==null ||taskInstances.isEmpty()){
                return CollUtil.newArrayList();
            }
            else{
                String assignee = taskInstances.get(0).getAssignee();
                return CollUtil.newArrayList(assignee);
            }


        }
        //服务
        else if(FlowTaskOperatorEnum.Serve.getCode().equals(assigneeType)){
            String url = userTaskBasicPropDTO.getGetUserUrl();
            String token = UserProvider.getToken();
            JSONObject object = HttpUtil.httpRequest(url, "GET", null, token);
            if (object != null) {
                if (object.get("data") != null) {
                    JSONObject data = object.getJSONObject("data");
                    List<String> handleId = StringUtil.isNotEmpty(data.getString("handleId")) ? Arrays.asList(data.getString("handleId").split(",")) : new ArrayList<>();
                    List<String> userAll = userList.stream().filter(t -> handleId.contains(t.getId())).map(t -> t.getId()).collect(Collectors.toList());
                    return CollUtil.newArrayList(userAll);
                }
                else{
                    return CollUtil.newArrayList();
                }
            }
            else{
                return CollUtil.newArrayList();
            }
        }
        //候选人员
        else if(FlowTaskOperatorEnum.CandidateUser.getCode().equals(assigneeType)){
            userIds.addAll(approvers);
            //角色和岗位下的用户  //乃至更多类型
            List<String> userRelationList=new ArrayList<>();
            if(ObjectUtil.isNotEmpty(approverPos) || ObjectUtil.isNotEmpty(approverRole)){
                userRelationList.addAll(approverPos);
                userRelationList.addAll(approverRole);
                List<UserRelationEntity> listByObjectIdAll = userRelationService.getListByObjectIdAll(userRelationList);
                List<String> userPosIds = listByObjectIdAll.stream().map(t -> t.getUserId()).collect(Collectors.toList());
                userIds.addAll(userPosIds);
            }
            //
            ArrayList<String> distinct = CollUtil.distinct(userIds);
            List<AvailableFlowDelegateDTO> availableFlowDelegateDTOList=new ArrayList<>();

            List<String> goOutList=new ArrayList<>();
            //判断这里面的人是不是有外出登记
            Iterator<String> iterator = distinct.iterator();
            while (iterator.hasNext()){
                String next = iterator.next();
                //外出登记判断
                AvailableFlowDelegateDTO availableFlowDelegateDTO = new AvailableFlowDelegateDTO();
                availableFlowDelegateDTO.setFlowId(flowId);
                availableFlowDelegateDTO.setCurrentUserId(next);
                availableFlowDelegateDTOList.add(availableFlowDelegateDTO);
                String processData = flowDelegateService.getAvailableProcessData(availableFlowDelegateDTO);
                if(StringUtils.isNotBlank(processData)){
                    iterator.remove();
                    goOutList.add(processData);
                }
            }
            distinct.addAll(goOutList);
            return distinct;
        }
        else{
            return CollUtil.newArrayList();
        }
        return CollUtil.newArrayList();
    }

    public   List<String> getAssignUserList(UserTaskExPropertyDTO userTaskExPropertyDTO, Map<String,String> taskInfoMap,String flowId) {
        String processDefinitionId = MapUtil.getStr(taskInfoMap, "processDefinitionId");
        String taskDefinitionKey = MapUtil.getStr(taskInfoMap, "taskDefinitionKey");
        String processInstanceId = MapUtil.getStr(taskInfoMap, "processInstanceId");
        ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager();
        ExecutionEntity rootExecutionEntity = executionEntityManager.findById(processInstanceId);

        if(StringUtils.isBlank(flowId)){
            flowId = rootExecutionEntity.getVariable(FLOW_ENGINE_ID).toString();
        }

        String businessKey = rootExecutionEntity.getProcessInstanceBusinessKey();
        String applyUserId = (String) rootExecutionEntity.getVariable(BasicActivitiConstants.startEventInitiator);
        UserTaskBasicPropDTO userTaskBasicPropDTO = userTaskExPropertyDTO.getUserTaskBasicPropDTO();
        UserTaskAdvancedSettingDTO userTaskAdvancedSettingDTO = userTaskExPropertyDTO.getUserTaskAdvancedSettingDTO();
        String assigneeType = userTaskBasicPropDTO.getAssigneeType();
        List<String> approvers = userTaskBasicPropDTO.getApprovers();
        List<String> approverPos = userTaskBasicPropDTO.getApproverPos();
        List<String> approverRole = userTaskBasicPropDTO.getApproverRole();
        List<UserEntity> userList = userService.getList();
        List<String> userIds=new ArrayList<>();
        //指定人员
        if(FlowTaskOperatorEnum.Nominator.getCode().equals(assigneeType)){
            userIds.addAll(approvers);
            //角色和岗位下的用户  //乃至更多类型
            List<String> userRelationList=new ArrayList<>();
            if(ObjectUtil.isNotEmpty(approverPos) || ObjectUtil.isNotEmpty(approverRole)){
                userRelationList.addAll(approverPos);
                userRelationList.addAll(approverRole);
                List<UserRelationEntity> listByObjectIdAll = userRelationService.getListByObjectIdAll(userRelationList);
                List<String> userPosIds = listByObjectIdAll.stream().map(t -> t.getUserId()).collect(Collectors.toList());
                userIds.addAll(userPosIds);
            }
            //
            ArrayList<String> distinct = CollUtil.distinct(userIds);
            List<String> goOutList=new ArrayList<>();
            //判断这里面的人是不是有外出登记
            Iterator<String> iterator = distinct.iterator();
            while (iterator.hasNext()){
                String next = iterator.next();
                //外出登记判断
                AvailableFlowDelegateDTO availableFlowDelegateDTO = new AvailableFlowDelegateDTO();
                availableFlowDelegateDTO.setFlowId(flowId);
                availableFlowDelegateDTO.setCurrentUserId(next);
                String processData = flowDelegateService.getAvailableProcessData(availableFlowDelegateDTO);
                if(StringUtils.isNotBlank(processData)){
                    iterator.remove();
                    goOutList.add(processData);
                }
            }
            distinct.addAll(goOutList);
            return distinct;
        }
        //发起者主管
        else if(FlowTaskOperatorEnum.LaunchCharge.getCode().equals(assigneeType)){
            //实时查用户主管
            UserEntity info = userService.getInfo(applyUserId);
            if (info != null) {
                String userId = getManagerByLevel(info.getManagerId(), userTaskBasicPropDTO.getManagerLevel(), userList);
                if(StringUtils.isBlank(userId)){
                    return CollUtil.newArrayList();
                }
                else{
                    //外出登记判断
                    AvailableFlowDelegateDTO availableFlowDelegateDTO = new AvailableFlowDelegateDTO();
                    availableFlowDelegateDTO.setFlowId(flowId);
                    availableFlowDelegateDTO.setCurrentUserId(userId);
                    String processData = flowDelegateService.getAvailableProcessData(availableFlowDelegateDTO);
                    if(StringUtils.isBlank(processData)){
                        return CollUtil.newArrayList(userId);
                    }
                    return CollUtil.newArrayList(processData);
                }

            }

        }
        //发起人本人
        else if(FlowTaskOperatorEnum.InitiatorMe.getCode().equals(assigneeType)){
            //外出登记判断
            AvailableFlowDelegateDTO availableFlowDelegateDTO = new AvailableFlowDelegateDTO();
            availableFlowDelegateDTO.setFlowId(flowId);
            availableFlowDelegateDTO.setCurrentUserId(applyUserId);
            String trueAssignee = flowDelegateService.getAvailableProcessData(availableFlowDelegateDTO);
            if(StringUtils.isNotBlank(trueAssignee)){
                return CollUtil.newArrayList(trueAssignee);
            }
            else{
                return CollUtil.newArrayList(applyUserId);
            }
        }
        //部门主管
        else if(FlowTaskOperatorEnum.DepartmentCharge.getCode().equals(assigneeType)){
            UserEntity userEntity = userService.getInfo(applyUserId);
            OrganizeEntity organizeEntity = organizeService.getInfo(userEntity != null ? userEntity.getOrganizeId() : "");
            if (organizeEntity != null) {
                String userId = organizeEntity.getManager();
                //外出登记判断
                AvailableFlowDelegateDTO availableFlowDelegateDTO = new AvailableFlowDelegateDTO();
                availableFlowDelegateDTO.setFlowId(flowId);
                availableFlowDelegateDTO.setCurrentUserId(userId);
                String trueAssignee = flowDelegateService.getAvailableProcessData(availableFlowDelegateDTO);
                if(StringUtils.isNotBlank(trueAssignee)){
                    return CollUtil.newArrayList(trueAssignee);
                }
                else{
                    return CollUtil.newArrayList(userId);
                }
            }
        }
        //变量
        else if(FlowTaskOperatorEnum.Variate.getCode().equals(assigneeType)){
            String formField = userTaskBasicPropDTO.getFormField();

            FormDataInfo formDataInfo = runtimeService.getVariable(processInstanceId, GlobalProcessVariableConstants.FORM_INFO_JSON, FormDataInfo.class);
            Map<String, Object> map = JsonUtil.stringToMap(formDataInfo.getFormDataJson());
            Object data = map.get(formField);
            if (data != null) {
                List<String> handleId = Arrays.asList(String.valueOf(data).split(","));
                List<String> userAll = userList.stream().filter(t -> handleId.contains(t.getId())).map(t -> t.getId()).collect(Collectors.toList());
                return CollUtil.newArrayList(userAll);
            }
            else{
                return CollUtil.newArrayList();
            }
        }
        //环节
        else if(FlowTaskOperatorEnum.Tache.getCode().equals(assigneeType)){
            //此有歧义 留给后续产品经理探讨
            String nodeId = userTaskBasicPropDTO.getNodeId();
            BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
            Process mainProcess = bpmnModel.getMainProcess();
            UserTask targetNode = (UserTask) bpmnModel.getFlowElement(nodeId);
            String property = getAttributeValueByTaskDefinitionKey(mainProcess, taskDefinitionKey, "userTask");
            UserTaskExPropertyDTO exPropertyDTO = JSONObject.parseObject(property, new TypeReference<UserTaskExPropertyDTO>() {
            });
            UserTaskBasicPropDTO nodeUserTaskBasicPropDTO = exPropertyDTO.getUserTaskBasicPropDTO();
            List<HistoricTaskInstance> taskInstances = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).finished().taskDefinitionKey(nodeId).orderByTaskCreateTime().desc().list();
            if(taskInstances==null ||taskInstances.isEmpty()){
                return CollUtil.newArrayList();
            }
            else{
                String assignee = taskInstances.get(0).getAssignee();
                return CollUtil.newArrayList(assignee);
            }


        }
        //服务
        else if(FlowTaskOperatorEnum.Serve.getCode().equals(assigneeType)){
            String url = userTaskBasicPropDTO.getGetUserUrl();
            String token = UserProvider.getToken();
            JSONObject object = HttpUtil.httpRequest(url, "GET", null, token);
            if (object != null) {
                if (object.get("data") != null) {
                    JSONObject data = object.getJSONObject("data");
                    List<String> handleId = StringUtil.isNotEmpty(data.getString("handleId")) ? Arrays.asList(data.getString("handleId").split(",")) : new ArrayList<>();
                    List<String> userAll = userList.stream().filter(t -> handleId.contains(t.getId())).map(t -> t.getId()).collect(Collectors.toList());
                    return CollUtil.newArrayList(userAll);
                }
                else{
                    return CollUtil.newArrayList();
                }
            }
            else{
                return CollUtil.newArrayList();
            }
        }
        //候选人员
        else if(FlowTaskOperatorEnum.CandidateUser.getCode().equals(assigneeType)){
            userIds.addAll(approvers);
            //角色和岗位下的用户  //乃至更多类型
            List<String> userRelationList=new ArrayList<>();
            if(ObjectUtil.isNotEmpty(approverPos) || ObjectUtil.isNotEmpty(approverRole)){
                userRelationList.addAll(approverPos);
                userRelationList.addAll(approverRole);
                List<UserRelationEntity> listByObjectIdAll = userRelationService.getListByObjectIdAll(userRelationList);
                List<String> userPosIds = listByObjectIdAll.stream().map(t -> t.getUserId()).collect(Collectors.toList());
                userIds.addAll(userPosIds);
            }
            //
            ArrayList<String> distinct = CollUtil.distinct(userIds);
            List<AvailableFlowDelegateDTO> availableFlowDelegateDTOList=new ArrayList<>();

            List<String> goOutList=new ArrayList<>();
            //判断这里面的人是不是有外出登记
            Iterator<String> iterator = distinct.iterator();
            while (iterator.hasNext()){
                String next = iterator.next();
                //外出登记判断
                AvailableFlowDelegateDTO availableFlowDelegateDTO = new AvailableFlowDelegateDTO();
                availableFlowDelegateDTO.setFlowId(flowId);
                availableFlowDelegateDTO.setCurrentUserId(next);
                availableFlowDelegateDTOList.add(availableFlowDelegateDTO);
                String processData = flowDelegateService.getAvailableProcessData(availableFlowDelegateDTO);
                if(StringUtils.isNotBlank(processData)){
                    iterator.remove();
                    goOutList.add(processData);
                }
            }
            distinct.addAll(goOutList);
            return distinct;
        }
        else{
            return CollUtil.newArrayList();
        }
        return CollUtil.newArrayList();
    }



    /**
     * 递归主管
     *
     * @param managerId 主管id
     * @param level     第几级
     * @return
     */
    private static String getManagerByLevel(String managerId, long level, List<UserEntity> userList) {
        --level;
        if (level == 0) {
            return managerId;
        } else {
            UserEntity userEntity = userList.stream().filter(t -> t.getId().equals(managerId)).findFirst().orElse(null);
            return userEntity != null ? getManagerByLevel(userEntity.getManagerId(), level, userList) : "";
        }
    }


    /**
     * 事件处理
     *
     * @param status    事件状态
     */
    public void event(Integer status, UserTaskExPropertyDTO userTaskExPropertyDTO, String processInstanceId,String taskEntityId) {
        UserTaskNodeEventDTO userTaskNodeEventDTO = userTaskExPropertyDTO.getUserTaskNodeEventDTO();
        String activityApprovalEventInterfaceType = userTaskNodeEventDTO.getActivityApprovalEventInterfaceType();
        String hasStartActivityWithdrawEventInterfaceType = userTaskNodeEventDTO.getHasStartActivityWithdrawEventInterfaceType();
        String startActivityEndEventInterfaceType = userTaskNodeEventDTO.getStartActivityEndEventInterfaceType();
        String startActivityStartEventInterfaceType = userTaskNodeEventDTO.getStartActivityStartEventInterfaceType();
        String activityWithdrawInterfaceType = userTaskNodeEventDTO.getActivityWithdrawInterfaceType();


        String activityApprovalEventURL = userTaskNodeEventDTO.getActivityApprovalEventURL();
        String activityWithdrawEventURL = userTaskNodeEventDTO.getActivityWithdrawEventURL();

        Boolean hasActivityApprovalEventEnable = userTaskNodeEventDTO.getHasActivityApprovalEventEnable();
        Boolean hasActivityWithdrawEventEnable = userTaskNodeEventDTO.getHasActivityWithdrawEventEnable();


        Boolean hasStartActivityStartEventEnable = userTaskNodeEventDTO.getHasStartActivityStartEventEnable();
        Boolean hasStartActivityWithdrawEventEnable = userTaskNodeEventDTO.getHasStartActivityWithdrawEventEnable();
        Boolean hasStartActivityEndEventEnable = userTaskNodeEventDTO.getHasStartActivityEndEventEnable();
        String startActivityEndEventURL = userTaskNodeEventDTO.getStartActivityEndEventURL();
        String startActivityStartEventURL = userTaskNodeEventDTO.getStartActivityStartEventURL();
        String startActivityWithdrawEventURL = userTaskNodeEventDTO.getStartActivityWithdrawEventURL();

        boolean flag = false;
        String faceUrl = "";
        //属性
        if (userTaskNodeEventDTO != null) {
            //审批事件
            if (FlowRecordEnum.audit.getCode().equals(status) || FlowRecordEnum.reject.getCode().equals(status)) {
                flag = hasActivityApprovalEventEnable != null ? hasActivityApprovalEventEnable : false;
                faceUrl = activityApprovalEventURL + "?" + taskNodeId + "=" + taskEntityId + "&" +
                        handleStatus + "=" + status + "&" + taskId + "=" + processInstanceId;
                System.out.println("进入节点事件:" + faceUrl);
            }
            //开始节点开始事件
            else if (FlowRecordEnum.submit.getCode().equals(status)) {
                flag = hasStartActivityStartEventEnable != null ? hasStartActivityStartEventEnable : false;
                faceUrl = startActivityStartEventURL + "?" + taskNodeId + "=" + taskEntityId +
                        "&" + taskId + "=" + processInstanceId;
                System.out.println("进入开始事件:" + faceUrl);
            }
            //开始节点撤回事件
            else if (FlowRecordEnum.revoke.getCode().equals(status)) {
                flag = hasStartActivityWithdrawEventEnable != null ? hasStartActivityWithdrawEventEnable : false;
                faceUrl = startActivityWithdrawEventURL+ "?" + handleStatus + "=" +
                        FlowRecordEnum.revoke.getCode()
                        + "&" + taskId + "=" + processInstanceId;
                System.out.println("开始撤回事件:" + faceUrl);
            }
            //开始节点结束事件
            else if (FlowRecordEnum.end.getCode().equals(status)) {
                flag = hasStartActivityEndEventEnable != null ? hasStartActivityEndEventEnable: false;
                faceUrl = startActivityEndEventURL + "?" + taskNodeId + "=" + taskId + "&" +
                        handleStatus + "=" + FlowRecordEnum.submit + "&" + taskId + "=" + processInstanceId;
                System.out.println("进入结束事件:" + faceUrl);
            }
            //
            else if (FlowRecordEnum.recall.getCode().equals(status)) {
                flag = hasActivityWithdrawEventEnable != null ? hasActivityWithdrawEventEnable : false;
                faceUrl = activityWithdrawEventURL + "?" + taskNodeId + "=" + taskId + "&" +
                        handleStatus + "=" + FlowRecordEnum.recall + "&" + taskId + "=" + processInstanceId;
                System.out.println("进入撤回事件:" + faceUrl);
            }
        }
        if (flag) {
            String token = UserProvider.getToken();
            HttpUtil.httpRequest(faceUrl, "GET", null, token);
        }
    }



    /**
     * 发送消息
     *
     */
    public void message(UserTaskExPropertyDTO userTaskExPropertyDTO,List<String> circulateListUserIds,TaskEntity taskEntity,List<String> assigneeUserIds,String fullName,String msgTitle) {
        List<SentMessageForm> messageList = new ArrayList<>();
        UserTaskAdvancedSettingDTO userTaskAdvancedSettingDTO = userTaskExPropertyDTO.getUserTaskAdvancedSettingDTO();
        List<String> messageType = userTaskAdvancedSettingDTO.getMessageType();
        //审批人
        if(assigneeUserIds!=null && !assigneeUserIds.isEmpty()){
            SentMessageForm sentMessageForm = this.message("【审核】", FlowMessageEnum.wait.getCode(), messageType, taskEntity, assigneeUserIds,fullName);
            messageList.add(sentMessageForm);
        }
        //抄送人
        if(circulateListUserIds!=null && !circulateListUserIds.isEmpty()){
            SentMessageForm sentMessageForm = this.message("【抄送】", FlowMessageEnum.circulate.getCode(), messageType, taskEntity, circulateListUserIds,fullName);
            messageList.add(sentMessageForm);
        }
        //流程结束通知发起人
        if (StringUtil.isNotEmpty(msgTitle)) {
            String applyUserId = taskEntity.getVariable(APPLY_USER_ID, String.class);
            List<String> userList = new ArrayList<>();
            userList.add(applyUserId);
            messageType.add(MessageTypeEnum.SysMessage.getCode());
            SentMessageForm sentMessageForm = this.message(msgTitle, FlowMessageEnum.me.getCode(), messageType, taskEntity, userList,fullName);
            messageList.add(sentMessageForm);
        }

        for (SentMessageForm messageForm : messageList) {
            sentMessageUtil.sendMessage(messageForm);
        }
    }

    /**
     * 发送消息封装
     *
     * @param title       名称
     * @param type        类型
     * @param messageType 发送消息类型
     * @param taskEntity  所有节点
     * @param userList    发送用户
     * @return
     */
    private SentMessageForm message(String title, int type, List<String> messageType, TaskEntity taskEntity, List<String> userList,String fullName) {
        SentMessageForm sentMessageForm = new SentMessageForm();
        sentMessageForm.setSendType(messageType);
        Map<String, Object> message = new HashMap<>(16);
        message.put("type", type);
        message.put("id", taskEntity.getProcessInstanceId());
        sentMessageForm.setContent(JsonUtilEx.getObjectToString(message));
        sentMessageForm.setTitle(fullName + title);
        sentMessageForm.setToUserIds(userList);
        Map<String, String> smsContent = new HashMap<>(16);
        this.message(fullName, title, smsContent);
        sentMessageForm.setSmsContent(smsContent);
        return sentMessageForm;
    }

    /**
     * 短信模板
     *
     * @param title  标题
     * @param status 状态
     * @return
     */
    private void message(String title, String status, Map<String, String> msg) {
        Map<String, String> aliyun = new HashMap<>(16);
        aliyun.put("title", title);
        aliyun.put("status", status);
        msg.put("1", JsonUtil.getObjectToString(aliyun));
        msg.put("2", "2");
    }

}