package com.yunzhupaas.flowable.util;

import cn.hutool.core.util.ObjectUtil;
import com.google.common.collect.ImmutableList;
import com.yunzhupaas.base.ActionResult;
import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.base.model.systemconfig.SysConfigModel;
import com.yunzhupaas.emnus.TemplateEnum;
import com.yunzhupaas.exception.WorkFlowException;
import com.yunzhupaas.flowable.entity.*;
import com.yunzhupaas.flowable.model.message.ContModel;
import com.yunzhupaas.flowable.model.message.DelegateModel;
import com.yunzhupaas.flowable.model.message.FlowEventModel;
import com.yunzhupaas.flowable.model.message.FlowMsgModel;
import com.yunzhupaas.flowable.model.task.FlowModel;
import com.yunzhupaas.flowable.model.templatenode.nodejson.*;
import com.yunzhupaas.flowable.model.util.FlowConstant;
import com.yunzhupaas.flowable.model.util.FlowNature;
import com.yunzhupaas.flowable.service.DelegateService;
import com.yunzhupaas.message.model.SentMessageForm;
import com.yunzhupaas.permission.entity.UserEntity;
import com.yunzhupaas.util.DateUtil;
import com.yunzhupaas.util.JsonUtil;
import com.yunzhupaas.util.StringUtil;
import com.yunzhupaas.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

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

/**
 * @author ：云筑产品开发平台组
 * @version: V3.1.0
 * @copyright 深圳市乐程软件有限公司
 * @date ：2022/3/30 11:45
 */
@Slf4j
@Component
public class MsgUtil {

    @Autowired
    private ServiceUtil serviceUtil;
    @Autowired
    private DelegateService delegateService;
    @Lazy
    @Autowired
    private FlowAsyncUtil flowAsyncUtil;

    public Map<String, Object> infoData(String formId, String taskId, Map<String, Map<String, Object>> allData) throws WorkFlowException {
        Map<String, Object> dataAll = allData.get(taskId + "_yunzhupaas_" + formId) != null ? allData.get(taskId + "_yunzhupaas_" + formId) : serviceUtil.infoData(formId, taskId);
        return dataAll;
    }

    /**
     * 发送消息
     *
     * @param flowMsgModel
     */
    public void message(FlowMsgModel flowMsgModel) throws WorkFlowException {
        List<SentMessageForm> messageListAll = new ArrayList<>();
        TaskEntity task = flowMsgModel.getTaskEntity();
        String taskId = task.getId();
        UserEntity user = StringUtil.isNotEmpty(task.getCreatorUserId()) ? serviceUtil.getUserInfo(task.getCreatorUserId()) : null;
        flowMsgModel.setCreateUser(user);
        UserEntity delegate = StringUtil.isNotEmpty(task.getDelegateUserId()) ? serviceUtil.getUserInfo(task.getDelegateUserId()) : null;
        flowMsgModel.setDelegate(delegate);
        Map<String, Map<String, Object>> formData = flowMsgModel.getFormData();
        String nodeCode = flowMsgModel.getNodeCode();
        List<TemplateNodeEntity> nodeList = flowMsgModel.getNodeList();
        List<OperatorEntity> operatorList = flowMsgModel.getOperatorList();
        List<CirculateEntity> circulateList = flowMsgModel.getCirculateList();
        TemplateNodeEntity startNodeEntity = nodeList.stream().filter(t -> FlowNature.NodeStart.equals(t.getNodeType())).findFirst().orElse(null);
        String nodeJson = startNodeEntity != null ? startNodeEntity.getNodeJson() : "{}";
        NodeModel startNode = JsonUtil.getJsonToBean(nodeJson, NodeModel.class);
        //同意
        if (flowMsgModel.getApprove()) {
            MsgConfig msgConfig = startNode.getApproveMsgConfig();
            TemplateNodeEntity taskNode = nodeList.stream().filter(t -> t.getNodeCode().equals(nodeCode)).findFirst().orElse(null);
            NodeModel taskChildNode = JsonUtil.getJsonToBean(taskNode.getNodeJson(), NodeModel.class);
            MsgConfig taskMsgConfig = taskChildNode.getApproveMsgConfig();
            if (taskMsgConfig.getOn() == 2) {
                taskMsgConfig = msgConfig;
            }
            if (taskMsgConfig.getOn() == 3) {
                taskMsgConfig.setMsgId("PZXTLC002");
            }
            List<SentMessageForm> messageList = new ArrayList<>();
            flowMsgModel.setOpType(FlowNature.LaunchDetail);
            Map<String, Object> data = this.infoData(startNode.getFormId(), taskId, formData);
            flowMsgModel.setData(data);
            flowMsgModel.setMsgConfig(taskMsgConfig);
            List<OperatorEntity> taskOperatorList = new ArrayList() {{
                OperatorEntity operatorEntity = new OperatorEntity();
                operatorEntity.setTaskId(task.getId());
                operatorEntity.setHandleId(task.getCreatorUserId());
                add(operatorEntity);
            }};
            FlowMsgModel msgModel = messageModel(taskOperatorList, flowMsgModel);
            setMessageList(messageList, msgModel);
            messageListAll.addAll(messageList);
        }
        // 拒绝
        if (flowMsgModel.getReject()) {
            MsgConfig msgConfig = startNode.getRejectMsgConfig();
            TemplateNodeEntity taskNode = nodeList.stream().filter(t -> t.getNodeCode().equals(nodeCode)).findFirst().orElse(null);
            NodeModel taskChildNode = JsonUtil.getJsonToBean(taskNode.getNodeJson(), NodeModel.class);
            MsgConfig taskMsgConfig = taskChildNode.getRejectMsgConfig();
            if (taskMsgConfig.getOn() == 2) {
                taskMsgConfig = msgConfig;
            }
            if (taskMsgConfig.getOn() == 3) {
                taskMsgConfig.setMsgId("PZXTLC018");
            }
            List<SentMessageForm> messageList = new ArrayList<>();
            flowMsgModel.setOpType(FlowNature.LaunchDetail);
            Map<String, Object> data = this.infoData(startNode.getFormId(), taskId, formData);
            flowMsgModel.setData(data);
            flowMsgModel.setMsgConfig(taskMsgConfig);
            List<OperatorEntity> taskOperatorList = new ArrayList() {{
                OperatorEntity operatorEntity = new OperatorEntity();
                operatorEntity.setTaskId(task.getId());
                operatorEntity.setHandleId(task.getCreatorUserId());
                add(operatorEntity);
            }};
            FlowMsgModel msgModel = messageModel(taskOperatorList, flowMsgModel);
            setMessageList(messageList, msgModel);
            messageListAll.addAll(messageList);
        }
        //等待
        if (flowMsgModel.getWait()) {
            MsgConfig taskMsgConfig = startNode.getWaitMsgConfig();
            if (taskMsgConfig.getOn() == 3) {
                if (flowMsgModel.getTransfer()) {
                    taskMsgConfig.setMsgId("PZXTLC006");
                } else if (flowMsgModel.getAssign()) {
                    taskMsgConfig.setMsgId("PZXTLC005");
                } else if (flowMsgModel.getPress()) {
                    taskMsgConfig.setMsgId("PZXTLC004");
                } else {
                    taskMsgConfig.setMsgId("PZXTLC001");
                }
            }
            Map<String, List<OperatorEntity>> operatorMap = operatorList.stream().collect(Collectors.groupingBy(OperatorEntity::getNodeCode));
            for (String key : operatorMap.keySet()) {
                List<SentMessageForm> messageList = new ArrayList<>();
                List<OperatorEntity> taskOperatorList = operatorMap.get(key);
                flowMsgModel.setOpType(FlowNature.WaitSign);
                TemplateNodeEntity taskNode = nodeList.stream().filter(t -> t.getNodeCode().equals(key)).findFirst().orElse(null);
                // 获取表单数据
                Map<String, Object> data = this.infoData(taskNode.getFormId(), taskId, formData);
                flowMsgModel.setData(data);
                flowMsgModel.setMsgConfig(taskMsgConfig);
                FlowMsgModel msgModel = messageModel(taskOperatorList, flowMsgModel);
                setMessageList(messageList, msgModel);
                messageListAll.addAll(messageList);
                for (OperatorEntity operator : taskOperatorList) {
                    List<SentMessageForm> delegationMsg = delegationMsg(operator, msgModel);
                    messageListAll.addAll(delegationMsg);
                }
            }
        }
        //结束
        if (flowMsgModel.getEnd()) {
            MsgConfig taskMsgConfig = startNode.getEndMsgConfig();
            if (taskMsgConfig.getOn() == 3) {
                taskMsgConfig.setMsgId("PZXTLC010");
            }
            List<SentMessageForm> messageList = new ArrayList<>();
            flowMsgModel.setOpType(FlowNature.LaunchDetail);
            Map<String, Object> data = this.infoData(startNode.getFormId(), taskId, formData);
            flowMsgModel.setData(data);
            flowMsgModel.setMsgConfig(taskMsgConfig);
            List<OperatorEntity> taskOperatorList = new ArrayList() {{
                OperatorEntity operatorEntity = new OperatorEntity();
                operatorEntity.setTaskId(task.getId());
                operatorEntity.setHandleId(task.getCreatorUserId());
                add(operatorEntity);
            }};
            FlowMsgModel msgModel = messageModel(taskOperatorList, flowMsgModel);
            setMessageList(messageList, msgModel);
            messageListAll.addAll(messageList);
        }
        //退回
        if (flowMsgModel.getBack()) {
            MsgConfig msgConfig = startNode.getBackMsgConfig();
            Map<String, List<OperatorEntity>> operatorMap = operatorList.stream().collect(Collectors.groupingBy(OperatorEntity::getNodeCode));
            for (String key : operatorMap.keySet()) {
                TemplateNodeEntity taskNode = nodeList.stream().filter(t -> t.getNodeCode().equals(nodeCode)).findFirst().orElse(null);
                NodeModel taskChildNode = JsonUtil.getJsonToBean(taskNode.getNodeJson(), NodeModel.class);
                MsgConfig taskMsgConfig = taskChildNode.getBackMsgConfig();
                if (taskMsgConfig.getOn() == 2) {
                    taskMsgConfig = msgConfig;
                }
                if (taskMsgConfig.getOn() == 3) {
                    taskMsgConfig.setMsgId("PZXTLC003");
                }
                List<SentMessageForm> messageList = new ArrayList<>();
                List<OperatorEntity> taskOperatorList = operatorMap.get(key);
                if (ObjectUtil.equals(flowMsgModel.getWait(), true)) {
                    flowMsgModel.setOpType(FlowNature.WaitSign);
                }
                Map<String, Object> data = this.infoData(taskNode.getFormId(), taskId, formData);
                flowMsgModel.setData(data);
                flowMsgModel.setMsgConfig(taskMsgConfig);
                FlowMsgModel msgModel = messageModel(taskOperatorList, flowMsgModel);
                setMessageList(messageList, msgModel);
                messageListAll.addAll(messageList);
                for (OperatorEntity operator : taskOperatorList) {
                    List<SentMessageForm> delegationMsg = delegationMsg(operator, msgModel);
                    messageListAll.addAll(delegationMsg);
                }
            }
        }
        //抄送
        if (flowMsgModel.getCopy()) {
            MsgConfig msgConfig = startNode.getCopyMsgConfig();
            Map<String, List<CirculateEntity>> circulateMap = circulateList.stream().collect(Collectors.groupingBy(CirculateEntity::getNodeCode));
            for (String key : circulateMap.keySet()) {
                TemplateNodeEntity taskNode = nodeList.stream().filter(t -> t.getNodeCode().equals(key)).findFirst().orElse(null);
                NodeModel taskChildNode = JsonUtil.getJsonToBean(taskNode.getNodeJson(), NodeModel.class);
                MsgConfig taskMsgConfig = taskChildNode.getCopyMsgConfig();
                if (taskMsgConfig.getOn() == 2) {
                    taskMsgConfig = msgConfig;
                }
                if (taskMsgConfig.getOn() == 3) {
                    taskMsgConfig.setMsgId("PZXTLC007");
                }
                List<SentMessageForm> messageList = new ArrayList<>();
                List<OperatorEntity> taskOperatorList = new ArrayList<>();
                for (CirculateEntity circulateEntity : circulateMap.get(key)) {
                    OperatorEntity operatorEntity = JsonUtil.getJsonToBean(circulateEntity, OperatorEntity.class);
                    operatorEntity.setHandleId(circulateEntity.getUserId());
                    taskOperatorList.add(operatorEntity);
                }
                flowMsgModel.setOpType(FlowNature.Circulate);
                Map<String, Object> data = this.infoData(taskNode.getFormId(), taskId, formData);
                flowMsgModel.setData(data);
                flowMsgModel.setMsgConfig(taskMsgConfig);
                FlowMsgModel msgModel = messageModel(taskOperatorList, flowMsgModel);
                setMessageList(messageList, msgModel);
                messageListAll.addAll(messageList);
            }
        }
        //子流程
        if (flowMsgModel.getLaunch()) {
            MsgConfig msgConfig = startNode.getLaunchMsgConfig();
            Map<String, List<OperatorEntity>> operatorMap = operatorList.stream().collect(Collectors.groupingBy(OperatorEntity::getNodeCode));
            for (String key : operatorMap.keySet()) {
                TemplateNodeEntity taskNode = nodeList.stream().filter(t -> t.getNodeCode().equals(key)).findFirst().orElse(null);
                NodeModel taskChildNode = JsonUtil.getJsonToBean(taskNode.getNodeJson(), NodeModel.class);
                MsgConfig taskMsgConfig = taskChildNode.getLaunchMsgConfig();
                if (taskMsgConfig.getOn() == 2) {
                    taskMsgConfig = msgConfig;
                }
                if (taskMsgConfig.getOn() == 3) {
                    taskMsgConfig.setMsgId("PZXTLC011");
                }
                List<SentMessageForm> messageList = new ArrayList<>();
                List<OperatorEntity> taskOperatorList = operatorMap.get(key);
                Map<String, Object> data = this.infoData(taskNode.getFormId(), taskId, formData);
                flowMsgModel.setData(data);
                flowMsgModel.setMsgConfig(taskMsgConfig);
                flowMsgModel.setOpType(taskChildNode.getAutoSubmit().equals(1) ? FlowNature.LaunchDetail : FlowNature.LaunchCreate);
                FlowMsgModel msgModel = messageModel(taskOperatorList, flowMsgModel);
                setMessageList(messageList, msgModel);
                messageListAll.addAll(messageList);
            }
        }
        //发起人
        if (flowMsgModel.getStart()) {
            MsgConfig msgConfig = startNode.getBackMsgConfig();
            if (msgConfig.getOn() == 3) {
                msgConfig.setMsgId("PZXTLC003");
            }
            List<SentMessageForm> messageList = new ArrayList<>();
            flowMsgModel.setOpType(FlowNature.LaunchDetail);
            Map<String, Object> data = this.infoData(startNode.getFormId(), taskId, formData);
            flowMsgModel.setData(data);
            List<OperatorEntity> meOperatorList = new ArrayList() {{
                OperatorEntity operatorEntity = new OperatorEntity();
                operatorEntity.setTaskId(taskId);
                operatorEntity.setHandleId(task.getCreatorUserId());
                add(operatorEntity);
            }};
            FlowMsgModel msgModel = messageModel(meOperatorList, flowMsgModel);
            setMessageList(messageList, msgModel);
            messageListAll.addAll(messageList);
        }
        //超时
        if (flowMsgModel.getOvertime()) {
            MsgConfig msgConfig = startNode.getOverTimeMsgConfig();
            Map<String, List<OperatorEntity>> operatorMap = operatorList.stream().collect(Collectors.groupingBy(OperatorEntity::getNodeCode));
            for (String key : operatorMap.keySet()) {
                TemplateNodeEntity taskNode = nodeList.stream().filter(t -> t.getNodeCode().equals(key)).findFirst().orElse(null);
                NodeModel taskChildNode = JsonUtil.getJsonToBean(taskNode.getNodeJson(), NodeModel.class);
                MsgConfig taskMsgConfig = taskChildNode.getOverTimeMsgConfig();
                if (taskMsgConfig.getOn() == 2) {
                    taskMsgConfig = msgConfig;
                }
                if (taskMsgConfig.getOn() == 3) {
                    taskMsgConfig.setMsgId("PZXTLC009");
                }
                List<SentMessageForm> messageList = new ArrayList<>();
                List<OperatorEntity> taskOperatorList = operatorMap.get(key);
                flowMsgModel.setOpType(FlowNature.WaitSign);
                Map<String, Object> data = this.infoData(taskNode.getFormId(), taskId, formData);
                flowMsgModel.setData(data);
                flowMsgModel.setMsgConfig(taskMsgConfig);
                FlowMsgModel msgModel = messageModel(taskOperatorList, flowMsgModel);
                setMessageList(messageList, msgModel);
                messageListAll.addAll(messageList);
                for (OperatorEntity operator : taskOperatorList) {
                    List<SentMessageForm> delegationMsg = delegationMsg(operator, flowMsgModel);
                    messageListAll.addAll(delegationMsg);
                }
            }
        }
        //提醒
        if (flowMsgModel.getNotice()) {
            MsgConfig msgConfig = startNode.getNoticeMsgConfig();
            Map<String, List<OperatorEntity>> operatorMap = operatorList.stream().collect(Collectors.groupingBy(OperatorEntity::getNodeCode));
            for (String key : operatorMap.keySet()) {
                TemplateNodeEntity taskNode = nodeList.stream().filter(t -> t.getNodeCode().equals(key)).findFirst().orElse(null);
                NodeModel taskChildNode = JsonUtil.getJsonToBean(taskNode.getNodeJson(), NodeModel.class);
                MsgConfig taskMsgConfig = taskChildNode.getNoticeMsgConfig();
                if (taskMsgConfig.getOn() == 2) {
                    taskMsgConfig = msgConfig;
                }
                if (taskMsgConfig.getOn() == 3) {
                    taskMsgConfig.setMsgId("PZXTLC008");
                }
                List<SentMessageForm> messageList = new ArrayList<>();
                List<OperatorEntity> taskOperatorList = operatorMap.get(key);
                flowMsgModel.setOpType(FlowNature.WaitSign);
                Map<String, Object> data = this.infoData(taskNode.getFormId(), taskId, formData);
                flowMsgModel.setData(data);
                flowMsgModel.setMsgConfig(taskMsgConfig);
                FlowMsgModel msgModel = messageModel(taskOperatorList, flowMsgModel);
                setMessageList(messageList, msgModel);
                messageListAll.addAll(messageList);
                for (OperatorEntity operator : taskOperatorList) {
                    List<SentMessageForm> delegationMsg = delegationMsg(operator, msgModel);
                    messageListAll.addAll(delegationMsg);
                }
            }
        }
        //评论
        if (flowMsgModel.getComment()) {
            MsgConfig msgConfig = startNode.getCommentMsgConfig();
            if (msgConfig.getOn() == 3) {
                msgConfig.setMsgId("PZXTLC017");
            }
            Map<String, List<OperatorEntity>> operatorMap = operatorList.stream().collect(Collectors.groupingBy(OperatorEntity::getNodeCode));
            for (String key : operatorMap.keySet()) {
                List<SentMessageForm> messageList = new ArrayList<>();
                List<OperatorEntity> taskOperatorList = operatorMap.get(key);
                flowMsgModel.setOpType(FlowNature.Circulate);
                TemplateNodeEntity taskNode = nodeList.stream().filter(t -> t.getNodeCode().equals(key)).findFirst().orElse(null);
                Map<String, Object> data = this.infoData(taskNode.getFormId(), taskId, formData);
                flowMsgModel.setData(data);
                flowMsgModel.setMsgConfig(msgConfig);
                FlowMsgModel msgModel = messageModel(taskOperatorList, flowMsgModel);
                setMessageList(messageList, msgModel);
                messageListAll.addAll(messageList);
            }
            //抄送
            Map<String, List<CirculateEntity>> circulateMap = circulateList.stream().collect(Collectors.groupingBy(CirculateEntity::getNodeCode));
            for (String key : circulateMap.keySet()) {
                TemplateNodeEntity taskNode = nodeList.stream().filter(t -> t.getNodeCode().equals(key)).findFirst().orElse(null);
                List<SentMessageForm> messageList = new ArrayList<>();
                List<OperatorEntity> taskOperatorList = new ArrayList<>();
                for (CirculateEntity circulateEntity : circulateMap.get(key)) {
                    OperatorEntity operatorEntity = JsonUtil.getJsonToBean(circulateEntity, OperatorEntity.class);
                    operatorEntity.setHandleId(circulateEntity.getUserId());
                    taskOperatorList.add(operatorEntity);
                }
                flowMsgModel.setOpType(FlowNature.Circulate);
                Map<String, Object> data = this.infoData(taskNode.getFormId(), taskId, formData);
                flowMsgModel.setData(data);
                flowMsgModel.setMsgConfig(msgConfig);
                FlowMsgModel msgModel = messageModel(taskOperatorList, flowMsgModel);
                setMessageList(messageList, msgModel);
                messageListAll.addAll(messageList);
            }
            if (flowMsgModel.getStartHandId()) {
                List<SentMessageForm> messageList = new ArrayList<>();
                flowMsgModel.setOpType(FlowNature.LaunchDetail);
                Map<String, Object> data = this.infoData(startNode.getFormId(), taskId, formData);
                flowMsgModel.setData(data);
                List<OperatorEntity> meOperatorList = new ArrayList() {{
                    OperatorEntity operatorEntity = new OperatorEntity();
                    operatorEntity.setTaskId(task.getId());
                    operatorEntity.setHandleId(task.getCreatorUserId());
                    add(operatorEntity);
                }};
                FlowMsgModel msgModel = messageModel(meOperatorList, flowMsgModel);
                setMessageList(messageList, msgModel);
                messageListAll.addAll(messageList);
            }
        }
        for (SentMessageForm sentMessageForm : messageListAll) {
            sentMessageForm.setFlowName(task.getFullName());
            sentMessageForm.setUserName(user != null ? user.getRealName() : "");
        }
        serviceUtil.sendMessage(messageListAll);
    }

    /**
     * 组装接口数据
     *
     * @return
     */
    public Map<String, String> parameterMap(Map<String, Object> data, List<TemplateJsonModel> templateJsonModelList, RecordEntity record, TaskEntity task) {
        List<String> creator = ImmutableList.of(
                FlowConstant.LAUNCH_USER_NAME,
                FlowConstant.CREATORUSERNAME,
                FlowConstant.MANDATOR
        );
        List<String> mandatary = ImmutableList.of(FlowConstant.MANDATARY);
        List<TemplateJsonModel> templateList = templateJsonModelList.stream().filter(e -> Objects.equals(e.getSourceType(), TemplateEnum.System.getCode())).collect(Collectors.toList());
        boolean isCreator = templateList.stream().anyMatch(e -> creator.contains(e.getRelationField()));
        UserEntity createUser = null;
        if (isCreator) {
            createUser = serviceUtil.getUserInfo(task.getCreatorUserId());
        }
        boolean isMandatary = templateList.stream().anyMatch(e -> mandatary.contains(e.getRelationField()));
        UserEntity delegate = null;
        if (isMandatary) {
            delegate = StringUtil.isNotEmpty(task.getDelegateUserId()) ? serviceUtil.getUserInfo(task.getDelegateUserId()) : null;
        }
        return parameterMap(data, templateJsonModelList, record, task, createUser, delegate);
    }

    /**
     * 组装接口数据
     *
     * @return
     */
    public Map<String, String> parameterMap(Map<String, Object> data, List<TemplateJsonModel> templateJsonModelList, RecordEntity record, TaskEntity task, UserEntity createUser, UserEntity delegate) {
        Map<String, String> parameterMap = new HashMap<>();
        for (TemplateJsonModel templateJsonModel : templateJsonModelList) {
            String fieldId = templateJsonModel.getField();
            String msgTemplateId = templateJsonModel.getMsgTemplateId();
            String relationField = templateJsonModel.getRelationField();
            String dataValue = data.get(relationField) != null ? String.valueOf(data.get(relationField)) : null;
            String dataFieldValue = relationField;
            String dataJson = Objects.equals(TemplateEnum.Field.getCode(), templateJsonModel.getSourceType()) ? dataValue : dataFieldValue;
            FlowEventModel eventModel = FlowEventModel.builder().data(data).dataJson(dataJson).record(record).templateJson(templateJsonModel).taskEntity(task).createUser(createUser).delegate(delegate).build();
            dataJson = data(eventModel);
            parameterMap.put(StringUtil.isNotEmpty(msgTemplateId) ? msgTemplateId : "" + fieldId, dataJson);
        }
        return parameterMap;
    }

    /**
     * @return
     */
    private String data(FlowEventModel eventModel) {
        RecordEntity record = eventModel.getRecord();
        TemplateJsonModel templateJson = eventModel.getTemplateJson();
        String relationField = StringUtil.isNotEmpty(templateJson.getRelationField()) ? templateJson.getRelationField() : "";
        List<Integer> typeList = ImmutableList.of(TemplateEnum.Field.getCode(), TemplateEnum.System.getCode());
        boolean isType = typeList.contains(templateJson.getSourceType());
        String dataJson = eventModel.getDataJson();
        Map<String, Object> data = eventModel.getData();
        UserInfo userInfo = UserProvider.getUser();
        String userId = userInfo.getUserId();
        String userName = userInfo.getUserName() != null ? userInfo.getUserName() : "";
        String value = dataJson;
        TaskEntity taskEntity = eventModel.getTaskEntity();
        if (isType) {
            switch (relationField) {
                case FlowConstant.FLOW_ID:
                    value = taskEntity.getFlowId();
                    break;
                case FlowConstant.TASK_ID:
                    value = taskEntity.getId();
                    break;
                case FlowConstant.TASK_NODE_ID:
                    value = record.getNodeCode();
                    break;
                case FlowConstant.FLOW_FULL_NAME:
                    value = taskEntity.getFlowName();
                    break;
                case FlowConstant.TASK_FULL_NAME:
                    value = taskEntity.getFullName();
                    break;
                case FlowConstant.LAUNCH_USER_ID:
                    value = taskEntity.getCreatorUserId();
                    break;
                case FlowConstant.LAUNCH_USER_NAME:
                case FlowConstant.CREATORUSERNAME:
                case FlowConstant.MANDATOR:
//                    UserEntity createUser = StringUtil.isNotBlank(taskEntity.getCreatorUserId()) ? serviceUtil.getUserInfo(taskEntity.getCreatorUserId()) : null;
                    UserEntity createUser = eventModel.getCreateUser();
                    value = createUser != null ? createUser.getRealName() : "";
                    break;
                case FlowConstant.FLOW_OPERATOR_USER_ID:
                    value = userId;
                    break;
                case FlowConstant.FLOW_OPERATOR_USER_NAME:
                    value = userName;
                    break;
                case FlowConstant.SENDTIME:
                    value = DateUtil.getNow();
                    break;
                case FlowConstant.MANDATARY:
//                    UserEntity delegate = StringUtil.isNotBlank(taskEntity.getDelegateUserId()) ? serviceUtil.getUserInfo(taskEntity.getDelegateUserId()) : null;
                    UserEntity delegate = eventModel.getDelegate();
                    value = delegate != null ? delegate.getRealName() : "";
                    break;
                default:
                    String[] model = StringUtil.isNotEmpty(relationField) ? relationField.split("-") : new String[]{};
                    if (model.length > 1) {
                        Object dataList = data.get(model[0]);
                        if (dataList instanceof List) {
                            List<Map<String, Object>> listAll = (List<Map<String, Object>>) dataList;
                            List<Object> list = new ArrayList<>();
                            for (Map<String, Object> objectMap : listAll) {
                                list.add(objectMap.get(model[1]));
                            }
                            value = String.valueOf(list);
                        }
                    }
                    break;
            }
        }
        return value;
    }

    private void setMessageList(List<SentMessageForm> messageList, FlowMsgModel flowMsgModel) {
        HashMap<String, Object> data = new HashMap<>(flowMsgModel.getData());
        MsgConfig msgConfig = flowMsgModel.getMsgConfig() != null ? flowMsgModel.getMsgConfig() : new MsgConfig();
        List<String> userList = flowMsgModel.getUserList();
        UserInfo userInfo = flowMsgModel.getFlowModel().getUserInfo();
        TaskEntity task = flowMsgModel.getTaskEntity();
        UserEntity createUser = flowMsgModel.getCreateUser();
        UserEntity delegate = flowMsgModel.getDelegate();
        if (!userList.isEmpty()) {
            String templateId = msgConfig.getOn() == 0 ? "0" : msgConfig.getMsgId();
            boolean sysMessage = msgConfig.getOn() != 0;
            //解析发送配置json，获取消息模板参数
            List<TemplateJsonModel> templateJson = new ArrayList<>();
            for (SendConfigJson configJson : msgConfig.getTemplateJson()) {
                List<TemplateJsonModel> paramJson = configJson.getParamJson();
                templateJson.addAll(paramJson);
                List<String> list = ImmutableList.of(FlowConstant.MANDATOR, FlowConstant.MANDATARY, FlowConstant.CREATORUSERNAME, FlowConstant.SENDTIME);
                for (String field : list) {
                    TemplateJsonModel jsonModel = new TemplateJsonModel();
                    jsonModel.setMsgTemplateId(configJson.getId());
                    jsonModel.setRelationField(field);
                    jsonModel.setField(field);
                    jsonModel.setSourceType(TemplateEnum.System.getCode());
                    templateJson.add(jsonModel);
                }
            }
            SentMessageForm sentMessageForm = new SentMessageForm();
            sentMessageForm.setSysMessage(sysMessage);
            sentMessageForm.setTemplateId(templateId);
            sentMessageForm.setToUserIds(userList);
            Map<String, Object> parameterMap = new HashMap<>();
            RecordEntity record = new RecordEntity();
            record.setNodeCode(flowMsgModel.getNodeCode());
            for (TemplateJsonModel templateJsonModel : templateJson) {
                String fieldId = templateJsonModel.getField();
                String msgTemplateId = templateJsonModel.getMsgTemplateId();
                String relationField = templateJsonModel.getRelationField();
                String dataValue = data.get(relationField) != null ? String.valueOf(data.get(relationField)) : "";
                String dataFieldValue = relationField;
                String dataJson = Objects.equals(TemplateEnum.Field.getCode(), templateJsonModel.getSourceType()) ? dataValue : dataFieldValue;
                FlowEventModel eventModel = FlowEventModel.builder().data(data).dataJson(dataJson).record(record).templateJson(templateJsonModel)
                        .taskEntity(task).createUser(createUser).delegate(delegate).build();
                dataJson = data(eventModel);
                parameterMap.put(msgTemplateId + fieldId, dataJson);
            }
            data.putAll(parameterMap);
            sentMessageForm.setUserInfo(userInfo);
            sentMessageForm.setParameterMap(data);
            sentMessageForm.setContentMsg(flowMsgModel.getContMsg());
            sentMessageForm.setTitle(task.getFullName());
            messageList.add(sentMessageForm);
        }
    }

    private FlowMsgModel messageModel(List<OperatorEntity> taskOperatorList, FlowMsgModel flowMsgModel) {
        FlowMsgModel msgModel = JsonUtil.getJsonToBean(flowMsgModel, FlowMsgModel.class);
        List<String> userList = new ArrayList<>();
        TaskEntity task = flowMsgModel.getTaskEntity();
        Map<String, String> contMsg = new HashMap<>();
        for (OperatorEntity taskOperator : taskOperatorList) {
            ContModel contModel = new ContModel();
            contModel.setFlowId(task.getFlowId());
            contModel.setOperatorId(taskOperator.getId());
            contModel.setTaskId(task.getId());
            contModel.setOpType(flowMsgModel.getOpType());
            if (StringUtil.equals(flowMsgModel.getOpType(), FlowNature.WaitSign)) {
                if (null == taskOperator.getSignTime() && null == taskOperator.getStartHandleTime() && null == taskOperator.getHandleStatus()) {
                    contModel.setOpType(FlowNature.WaitSign);
                } else if (null != taskOperator.getSignTime() && null == taskOperator.getStartHandleTime() && null == taskOperator.getHandleStatus()) {
                    contModel.setOpType(FlowNature.Todo);
                } else if (null != taskOperator.getSignTime() && null != taskOperator.getStartHandleTime() && null == taskOperator.getHandleStatus()) {
                    contModel.setOpType(FlowNature.Doing);
                }
            }
            contMsg.put(taskOperator.getHandleId(), JsonUtil.getObjectToString(contModel));
            userList.add(taskOperator.getHandleId());
        }
        msgModel.setUserList(userList);
        msgModel.setContMsg(contMsg);
        return msgModel;
    }

    private List<SentMessageForm> delegationMsg(OperatorEntity operator, FlowMsgModel flowMsgModel) {
        List<SentMessageForm> messageList = new ArrayList<>();
        TaskEntity task = flowMsgModel.getTaskEntity();
        if (task != null) {
            // 获取委托人
            List<String> userList = delegateService.getToUser(operator.getHandleId(), task.getFlowId());
            List<OperatorEntity> operatorList = new ArrayList<>();
            for (String user : userList) {
                OperatorEntity delegate = JsonUtil.getJsonToBean(operator, OperatorEntity.class);
                delegate.setHandleId(user);
                operatorList.add(delegate);
                FlowMsgModel msgModel = messageModel(operatorList, flowMsgModel);
                setMessageList(messageList, msgModel);
            }
        }
        return messageList;
    }


    //--------------------------------------委托消息------------------------------------------------------
    public void delegateMsg(DelegateModel flowDelegate) {
        SysConfigModel sysConfig = serviceUtil.getSysConfig();
        Integer ack = flowDelegate.getDelegate() ? sysConfig.getDelegateAck() : sysConfig.getProxyAck();
        flowDelegate.setAck(ack);
        flowAsyncUtil.delegateMsg(flowDelegate);
    }

    /**
     * 流程事件
     *
     * @param status    事件状态 1.发起 2.结束 3.发起撤回 4同意 5拒绝 6节点撤回 7 超时 8提醒 9退回
     * @param nodeModel 节点数据
     * @param record    审批数据
     */
    public void event(Integer status, NodeModel nodeModel, RecordEntity record, FlowModel flowModel) {
        if (nodeModel != null) {
            boolean on = false;
            String interId = "";
            List<TemplateJsonModel> templateJsonModelList = new ArrayList<>();
            FuncConfig config = null;
            switch (status) {
                case 1:
                    config = nodeModel.getInitFuncConfig();
                    break;
                case 2:
                    config = nodeModel.getEndFuncConfig();
                    break;
                case 3:
                    config = nodeModel.getFlowRecallFuncConfig();
                    break;
                case 4:
                    config = nodeModel.getApproveFuncConfig();
                    break;
                case 5:
                    config = nodeModel.getRejectFuncConfig();
                    break;
                case 6:
                    config = nodeModel.getRecallFuncConfig();
                    break;
                case 7:
                    config = nodeModel.getOvertimeFuncConfig();
                    break;
                case 8:
                    config = nodeModel.getNoticeFuncConfig();
                    break;
                case 9:
                    config = nodeModel.getBackFuncConfig();
                    break;
                default:
                    break;
            }
            if (config != null) {
                on = config.getOn();
                interId = config.getInterfaceId();
                templateJsonModelList = config.getTemplateJson();
            }
            if (on && StringUtil.isNotEmpty(interId)) {
                Map<String, Object> data = flowModel.getFormData();
                TaskEntity taskEntity = flowModel.getTaskEntity();
//                UserEntity createUser = null;
//                UserEntity delegate = null;
//                if (taskEntity != null) {
//                    createUser = serviceUtil.getUserInfo(taskEntity.getCreatorUserId());
//                    delegate = StringUtil.isNotEmpty(taskEntity.getDelegateUserId()) ? serviceUtil.getUserInfo(taskEntity.getDelegateUserId()) : null;
//                }
                Map<String, String> parameterMap = parameterMap(data, templateJsonModelList, record, taskEntity);
                ActionResult result = serviceUtil.infoToId(interId, parameterMap);
                if (null == result || Objects.equals(400, result.getCode())) {
                    log.error("接口调用失败: {}", result);
                }
            }
        }
    }

    // 接口调用的参数需转为字符串
    public Map<String, String> intefaceParameterMap(Map<String, Object> data, List<TemplateJsonModel> templateJsonModelList, RecordEntity record, TaskEntity task, UserEntity createUser, UserEntity delegate) {
        Map<String, String> parameterMap = new HashMap<>();
        for (TemplateJsonModel templateJsonModel : templateJsonModelList) {
            String fieldId = templateJsonModel.getField();
            String msgTemplateId = templateJsonModel.getMsgTemplateId();
            String relationField = templateJsonModel.getRelationField();
            String dataValue = data.get(relationField) != null ? JsonUtil.getObjectToString(data.get(relationField)) : null;
            String dataFieldValue = relationField;
            String dataJson = Objects.equals(TemplateEnum.Field.getCode(), templateJsonModel.getSourceType()) ? dataValue : dataFieldValue;
            FlowEventModel eventModel = FlowEventModel.builder().data(data).dataJson(dataJson).record(record).templateJson(templateJsonModel).taskEntity(task).createUser(createUser).delegate(delegate).build();
            dataJson = data(eventModel);
            parameterMap.put(StringUtil.isNotEmpty(msgTemplateId) ? msgTemplateId : "" + fieldId, dataJson);
        }
        return parameterMap;
    }
}

