package cn.iocoder.yudao.module.bpm.service.message;

import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.util.corp.CorpMsgUtil;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.framework.web.config.WebProperties;
import cn.iocoder.yudao.module.bpm.convert.message.BpmMessageConvert;
import cn.iocoder.yudao.module.bpm.dal.dataobject.business.BpmBusinessFormDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.TaskCopyDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceCopyDO;
import cn.iocoder.yudao.module.bpm.dal.mysql.business.BpmBusinessFormMapper;
import cn.iocoder.yudao.module.bpm.dal.mysql.definition.TaskCopyMapper;
import cn.iocoder.yudao.module.bpm.dal.mysql.definition.TaskCopyUserMapper;
import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceCopyMapper;
import cn.iocoder.yudao.module.bpm.enums.BpmBusinessTypeEnum;
import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskApproveMethodEnum;
import cn.iocoder.yudao.module.bpm.enums.message.BpmMessageEnum;
import cn.iocoder.yudao.module.bpm.enums.message.BpmMessageStatusEnum;
import cn.iocoder.yudao.module.bpm.enums.task.BpmMultiTaskEnum;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.storage.RequestScopedStorage;
import cn.iocoder.yudao.module.bpm.service.business.BpmBusinessFormService;
import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO;
import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceRejectReqDTO;
import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskTimeoutReqDTO;
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
import cn.iocoder.yudao.module.system.api.bpm.BpmCheckInApi;
import cn.iocoder.yudao.module.system.api.bpm.BpmCheckInWaitApi;
import cn.iocoder.yudao.module.system.api.bpm.BpmElderlyApi;
import cn.iocoder.yudao.module.system.api.bpm.BpmElderlyChangeApi;
import cn.iocoder.yudao.module.system.api.bpm.vo.ElderlyInfoReqVO;
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
import cn.iocoder.yudao.module.system.api.sms.SmsSendApi;
import cn.iocoder.yudao.module.system.api.tenant.TenantApi;
import cn.iocoder.yudao.module.system.api.tenant.TenantRespDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import cn.iocoder.yudao.module.system.api.wechat.dto.CorpSendMessage;
import cn.iocoder.yudao.module.system.api.wechat.dto.CorpWechatTextcard;
import cn.iocoder.yudao.module.system.api.wechat.dto.WechatMessageSaveReq;
import cn.iocoder.yudao.module.system.enums.notice.NotieBusinessTypeEnum;
import cn.iocoder.yudao.module.system.enums.notice.NotifyPriorityEnum;
import cn.iocoder.yudao.module.system.enums.notice.NotifyTypeEnum;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.HistoryService;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.*;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.START_USER_NODE_ID;
import static cn.iocoder.yudao.module.system.enums.oauth2.EnterpriseWeChatConstants.BPM_DETAIL_URL;

/**
 * BPM 消息 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
@Slf4j
public class BpmMessageServiceImpl implements BpmMessageService {

    @Resource
    private SmsSendApi smsSendApi;

    @Resource
    private NotifyMessageSendApi notifyMessageSendApi;
    @Resource
    private WebProperties webProperties;

    @Resource
    private BpmBusinessFormMapper bpmBusinessFormMapper;

    @Resource
    private BpmBusinessFormService businessFormService;

    @Resource
    private BpmElderlyApi bpmElderlyApi;
    @Autowired
    private BpmCheckInWaitApi bpmCheckInWaitApi;

    @Resource
    private BpmElderlyChangeApi bpmElderlyChangeApi;

    @Resource
    private AdminUserApi adminUserApi;

    @Resource
    private TenantApi tenantApi;

    @Resource
    private BpmCheckInApi checkInApi;

    @Resource
    private TaskCopyMapper taskCopyMapper;

    @Resource
    private TaskCopyUserMapper taskCopyUserMapper;

    @Resource
    private BpmProcessInstanceCopyMapper processInstanceCopyMapper;

    @Resource
    @Lazy // 延迟加载，避免循环依赖
    private BpmProcessDefinitionService processDefinitionService;

    @Resource
    @Lazy // 延迟加载，避免循环依赖
    private BpmTaskService taskService;

    @Resource
    @Lazy // 延迟加载，避免循环依赖
    private BpmProcessInstanceService processInstanceService;

    @Resource
    private HistoryService historyService;

    @Autowired
    private RequestScopedStorage requestScopedStorage;

    @Override
    public void sendMessageWhenProcessInstanceApprove(BpmMessageSendWhenProcessInstanceApproveReqDTO reqDTO) {
        Map<String, Object> templateParams = new HashMap<>();
        templateParams.put("processInstanceName", reqDTO.getProcessInstanceName());
        templateParams.put("detailUrl", getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId()));
//        smsSendApi.sendSingleSmsToAdmin(BpmMessageConvert.INSTANCE.convert(reqDTO.getStartUserId(),
//                BpmMessageEnum.PROCESS_INSTANCE_APPROVE.getTemplateCode(), templateParams));
        // TODO 暂时注释
        sendApproveMessageByType(reqDTO, templateParams);
//        completeMessage(reqDTO.getProcessInstanceId(), "", reqDTO.getMultiTaskValue(), 2);
         // TODO 多人审批同意方式待处理
        notifyMessageSendApi.updateSelfMessageStatus(reqDTO.getProcessInstanceId(), "", null, null,
                BpmMessageStatusEnum.COMPLETE.getValue(), null,  Boolean.FALSE);
    }

    @Override
    public void sendMessageWhenProcessInstanceReject(BpmMessageSendWhenProcessInstanceRejectReqDTO reqDTO) {
        Map<String, Object> templateParams = new HashMap<>();
        templateParams.put("processInstanceName", reqDTO.getProcessInstanceName());
        templateParams.put("reason", reqDTO.getReason());
        templateParams.put("detailUrl", getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId()));
        smsSendApi.sendSingleSmsToAdmin(BpmMessageConvert.INSTANCE.convert(reqDTO.getStartUserId(),
                BpmMessageEnum.PROCESS_INSTANCE_REJECT.getTemplateCode(), templateParams));
        // 多人审批拒绝方式全部完成代办
        notifyMessageSendApi.updateSelfMessageStatus(reqDTO.getProcessInstanceId(), "", null, null,
                BpmMessageStatusEnum.COMPLETE.getValue(), null,  Boolean.FALSE);

        sendRejectMessageByType(reqDTO, templateParams);
//        completeMessage(reqDTO.getProcessInstanceId(), "", reqDTO.getMultiTaskValue(), 2);

    }

    @Override
    public void sendMessageWhenTaskAssigned(BpmMessageSendWhenTaskCreatedReqDTO reqDTO) {
        Map<String, Object> templateParams = new HashMap<>();
        templateParams.put("processInstanceName", reqDTO.getProcessInstanceName());
        templateParams.put("taskName", reqDTO.getTaskName());
        templateParams.put("startUserNickname", reqDTO.getStartUserNickname());
        templateParams.put("detailUrl", getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId()));
//        smsSendApi.sendSingleSmsToAdmin(BpmMessageConvert.INSTANCE.convert(reqDTO.getAssigneeUserId(),
//                BpmMessageEnum.TASK_ASSIGNED.getTemplateCode(), templateParams));
//        completeMessage(reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), reqDTO.getMultiTaskValue(), reqDTO.getPosition());

//        notifyMessageSendApi.updateSelfMessageStatus(reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), getLoginUserId(),
//                BpmMessageStatusEnum.COMPLETE.getValue(), reqDTO.getApproveMethod(),  reqDTO.getStartNodeFlag());
//        completeMessage(reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), reqDTO.getApproveMethod(), reqDTO.getAssigneeUserId(), reqDTO.getCurrentTaskIdMap());

        completeTaskAssignedMessage(reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), reqDTO.getApproveMethod(), reqDTO.getAssigneeUserId(), reqDTO.getStartNodeFlag(), reqDTO.getRequestSort());

        sendTaskAssignedMessageByType(reqDTO, templateParams, reqDTO.getApproveMethod(), reqDTO.getStartNodeFlag());

    }

    private void completeTaskAssignedMessage(String processInstanceId, String taskId, Integer approveMethod, Long assigneeUserId, Boolean startNodeFlag, int requestSort) {
        Long userId = getLoginUserId();
        Boolean backFlag = Boolean.FALSE;
        if (BpmUserTaskApproveMethodEnum.RANDOM.getMethod() == approveMethod) {
            userId = null;
            taskId = null;
        }
        if (BpmUserTaskApproveMethodEnum.RATIO.getMethod() == approveMethod) {

        }
        if (BpmUserTaskApproveMethodEnum.ANY.getMethod() == approveMethod && !startNodeFlag && requestSort > 0) {
            userId = assigneeUserId;
        }
        if (BpmUserTaskApproveMethodEnum.SEQUENTIAL.getMethod() == approveMethod) {
            taskId = null;
        }
        // 退回完成消息，全部完成当前消息
        if (null == approveMethod && startNodeFlag && requestSort > 0) {
            userId = null;
            backFlag = true;
        }

        if (!startNodeFlag || backFlag) {
            notifyMessageSendApi.updateSelfMessageStatus(processInstanceId, taskId, userId, assigneeUserId,
                    BpmMessageStatusEnum.COMPLETE.getValue(), approveMethod,  startNodeFlag);
        }
    }


    private void completeMessage(String processInstanceId, String taskId, Integer approveMethod, Long assigneeUserId, Map<String, String> currentTaskIdMap) {
        Long userId = getLoginUserId();
        Integer completedStatus = BpmMessageStatusEnum.COMPLETE.getValue();

        if (BpmUserTaskApproveMethodEnum.RANDOM.getMethod() == approveMethod) {
            userId = null;
            taskId = null;
        }
        if (BpmUserTaskApproveMethodEnum.RATIO.getMethod() == approveMethod) {

        }
        if (BpmUserTaskApproveMethodEnum.ANY.getMethod() == approveMethod) {

            userId = getLoginUserId();
        }
        if (BpmUserTaskApproveMethodEnum.SEQUENTIAL.getMethod() == approveMethod) {
            taskId = null;
        }


//        if (null == multiTaskValue || 0 == multiTaskValue) {
//            notifyMessageSendApi.updateMessageStatus(processInstanceId, taskId, getLoginUserId(), BpmMessageStatusEnum.COMPLETE.getValue());
//        }
//
//        if (BpmMultiTaskEnum.APPROVAL_IN_SEQUENCE.getValue().equals(multiTaskValue)) {
//            notifyMessageSendApi.updateMessageStatus(processInstanceId, taskId, getLoginUserId(), BpmMessageStatusEnum.COMPLETE.getValue());
//        }
//
//        if (BpmMultiTaskEnum.COUNTERSIGN.getValue().equals(multiTaskValue)) {
//            notifyMessageSendApi.updateSelfMessageStatus(processInstanceId, taskId, getLoginUserId(), BpmMessageStatusEnum.COMPLETE.getValue());
//        }
//
//        if (null == multiTaskValue || BpmMultiTaskEnum.ANY_ONE.getValue().equals(multiTaskValue)) {
//            notifyMessageSendApi.updateSelfMessageStatus(processInstanceId, taskId, null, BpmMessageStatusEnum.COMPLETE.getValue());
//        }
        notifyMessageSendApi.updateSelfMessageStatus(processInstanceId, taskId, userId, null, completedStatus, approveMethod, null);

    }

    @Override
    public void sendMessageWhenTaskTimeout(BpmMessageSendWhenTaskTimeoutReqDTO reqDTO) {
        Map<String, Object> templateParams = new HashMap<>();
        templateParams.put("processInstanceName", reqDTO.getProcessInstanceName());
        templateParams.put("taskName", reqDTO.getTaskName());
        templateParams.put("detailUrl", getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId()));
        smsSendApi.sendSingleSmsToAdmin(BpmMessageConvert.INSTANCE.convert(reqDTO.getAssigneeUserId(),
                BpmMessageEnum.TASK_TIMEOUT.getTemplateCode(), templateParams));
    }

    private void sendApproveMessageByType(BpmMessageSendWhenProcessInstanceApproveReqDTO reqDTO,
                                          Map<String, Object> templateParams) {
        BpmBusinessFormDO businessFormDO = businessFormService.selectOneByProcessInstanceId(reqDTO.getProcessInstanceId());
        TenantRespDTO tenant = tenantApi.getTenant(businessFormDO.getStartTenantId());
        String detailUrl = "";
        AdminUserRespDTO user = adminUserApi.getUserTenantIgnore(businessFormDO.getUserId());
        AdminUserRespDTO assigneeUser = adminUserApi.getUserTenantIgnore(reqDTO.getStartUserId());
        ElderlyInfoReqVO elderlyInfo = null;
        CorpSendMessage corpSendMessage = new CorpSendMessage();
        WechatMessageSaveReq wechatMessageSaveReq = new WechatMessageSaveReq();
        NotifySendSingleToUserReqDTO notifySendSingleToUserReqDTO = null;
        switch (BpmBusinessTypeEnum.valueOf(businessFormDO.getType())) {
            case APPLY_ACCOMMODATION:
                elderlyInfo = bpmElderlyApi.getElderlyInfo(businessFormDO.getBusinessId2());
                templateParams.put("nickname", user.getNickname());
                templateParams.put("elderName", elderlyInfo.getElderName());
                detailUrl = getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
                templateParams.put("detailUrl", detailUrl);
                notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getStartUserId(),
                        reqDTO.getProcessInstanceId(), "", detailUrl,
                        BpmMessageEnum.PROCESS_INSTANCE_APPROVE.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                        NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
                break;
            case APPLY_RETREAT:
                elderlyInfo = bpmElderlyApi.getElderlyInfoByRetreatId(businessFormDO.getBusinessId());
                templateParams.put("nickname", user.getNickname());
                templateParams.put("elderName", elderlyInfo.getElderName());
                detailUrl = getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
                templateParams.put("detailUrl", detailUrl);
                notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getStartUserId(),
                        reqDTO.getProcessInstanceId(), "", detailUrl,
                        BpmMessageEnum.RETREAT_PROCESS_INSTANCE_APPROVE.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                        NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
                break;
            case BED_CHANGE:
                elderlyInfo = bpmElderlyChangeApi.getElderlyInfoByChangeId(businessFormDO.getBusinessId());
                templateParams.put("nickname", user.getNickname());
                templateParams.put("elderName", elderlyInfo.getElderName());
                detailUrl = getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
                templateParams.put("detailUrl", detailUrl);
                notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getStartUserId(),
                        reqDTO.getProcessInstanceId(), "", detailUrl,
                        BpmMessageEnum.BED_CHANGE_PROCESS_INSTANCE_APPROVE.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                        NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
                break;
            case NURSE_CHANGE:
                elderlyInfo = bpmElderlyChangeApi.getElderlyInfoByChangeId(businessFormDO.getBusinessId());
                templateParams.put("nickname", user.getNickname());
                templateParams.put("elderName", elderlyInfo.getElderName());
                detailUrl = getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
                templateParams.put("detailUrl", detailUrl);
                notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getStartUserId(),
                        reqDTO.getProcessInstanceId(), "", detailUrl,
                        BpmMessageEnum.NURSE_CHANGE_PROCESS_INSTANCE_APPROVE.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                        NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
                break;
            case CATERING_CHANGE:
                elderlyInfo = bpmElderlyChangeApi.getElderlyInfoByChangeId(businessFormDO.getBusinessId());
                templateParams.put("nickname", user.getNickname());
                templateParams.put("elderName", elderlyInfo.getElderName());
                detailUrl = getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
                templateParams.put("detailUrl", detailUrl);
                notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getStartUserId(),
                        reqDTO.getProcessInstanceId(), "", detailUrl,
                        BpmMessageEnum.CATERING_CHANGE_PROCESS_INSTANCE_APPROVE.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                        NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
                break;
            case PRICE_CHANGE:
                elderlyInfo = bpmElderlyChangeApi.getElderlyInfoByChangeId(businessFormDO.getBusinessId());
                templateParams.put("nickname", user.getNickname());
                templateParams.put("elderName", elderlyInfo.getElderName());
                detailUrl = getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
                templateParams.put("detailUrl", detailUrl);
                notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getStartUserId(),
                        reqDTO.getProcessInstanceId(), "", detailUrl,
                        BpmMessageEnum.PRICE_CHANGE_PROCESS_INSTANCE_APPROVE.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                        NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());

                break;
            case TRANSFER_CHANGE:
                elderlyInfo = bpmElderlyChangeApi.getElderlyInfoByChangeId(businessFormDO.getBusinessId());
                templateParams.put("nickname", user.getNickname());
                templateParams.put("elderName", elderlyInfo.getElderName());
                detailUrl = getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
                templateParams.put("detailUrl", detailUrl);
                notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getStartUserId(),
                        reqDTO.getProcessInstanceId(), "", detailUrl,
                        BpmMessageEnum.TRANSFER_CHANGE_PROCESS_INSTANCE_APPROVES.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                        NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
            case CHECK_IN:
                elderlyInfo = bpmElderlyApi.getElderlyInfo(businessFormDO.getBusinessId2());
                templateParams.put("nickname", user.getNickname());
                templateParams.put("elderName", elderlyInfo.getElderName());
                detailUrl = getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
                templateParams.put("detailUrl", detailUrl);
                notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getStartUserId(),
                        reqDTO.getProcessInstanceId(), "", detailUrl,
                        BpmMessageEnum.CHECK_IN_PROCESS_INSTANCE_APPROVE.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                        NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
                break;
            case CHECK_IN_WAIT:
                JSONObject checkInWaitInfo = bpmCheckInWaitApi.selectById(businessFormDO.getBusinessId2());
                templateParams.put("nickname", user.getNickname());
                templateParams.put("elderName", checkInWaitInfo.getString("elderName"));
                detailUrl = getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
                templateParams.put("detailUrl", detailUrl);
                notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getStartUserId(),
                        reqDTO.getProcessInstanceId(), "", detailUrl,
                        BpmMessageEnum.CHECK_IN_WAIT_PROCESS_INSTANCE_APPROVE.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                        NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
                break;
            default:
                break;

        }
        String corpUserId = assigneeUser.getCorpUserId() == null ? "" : assigneeUser.getCorpUserId().toString();
        CorpWechatTextcard corpTextCard = new CorpWechatTextcard();
        corpTextCard.setTitle(CorpMsgUtil.TITLE_APPROVE);
        corpTextCard.setBtntxt(CorpMsgUtil.BTNTXT_DETAIL_NOTICE);
        corpTextCard.setUrl(String.format(BPM_DETAIL_URL, reqDTO.getProcessInstanceId(), 1, businessFormDO.getStatus()));
        corpSendMessage.setTouser(corpUserId);
        corpSendMessage.setTextcard(corpTextCard);
        wechatMessageSaveReq.setTitle(CorpMsgUtil.TITLE_APPROVE);
        wechatMessageSaveReq.setPkMessage(reqDTO.getProcessInstanceId());
        wechatMessageSaveReq.setPkMessage2("");
        wechatMessageSaveReq.setCorpUserId(corpUserId);
        wechatMessageSaveReq.setStartTenantId(assigneeUser.getTenantId());
        wechatMessageSaveReq.setTenantName(tenant.getAbbreviation());
        wechatMessageSaveReq.setTypeName(reqDTO.getProcessInstanceName());
        wechatMessageSaveReq.setApplyTime(DateUtils.localDateTimeToStr(businessFormDO.getCreateTime()));
        corpSendMessage.setWechatMessageSaveReq(wechatMessageSaveReq);
        notifyMessageSendApi.sendMessageAndCorpMessage(notifySendSingleToUserReqDTO, corpSendMessage);
        // TODO
        sendCopyUser(reqDTO, templateParams, detailUrl, tenant, businessFormDO);
    }

    private void sendCopyUser(BpmMessageSendWhenProcessInstanceApproveReqDTO reqDTO, Map<String, Object> templateParams,
                              String detailUrl, TenantRespDTO tenant,BpmBusinessFormDO businessFormDO) {
        List<TaskCopyDO> taskCopyDOList = taskCopyMapper.selectList(new LambdaQueryWrapper<TaskCopyDO>()
                .eq(TaskCopyDO::getProcessDefinitionId, reqDTO.getProcessDefinitionId())
                .eq(TaskCopyDO::getCurrentFlag, 0));
        if (taskCopyDOList == null || taskCopyDOList.size() == 0) {
            return;
        }
        taskCopyDOList.stream().max(Comparator.comparing(TaskCopyDO::getSort)).get();
        TaskCopyDO taskCopyDO = taskCopyDOList.stream().max(Comparator.comparing(TaskCopyDO::getSort)).get();
        List<AdminUserRespDTO> taskCopyUserDOList = taskCopyUserMapper.selectUserList(taskCopyDO.getId());
        if (taskCopyUserDOList == null || taskCopyUserDOList.size() == 0) {
            return;
        }

        List<String> ids = new ArrayList<>();
        ids.add(reqDTO.getProcessInstanceId());

        List<Task> taskInstanceList = taskService.getTasksByProcessInstanceIds(ids);
        Task task = taskInstanceList.stream().reduce((first, second) -> second).get();
        if (ObjectUtil.isNull(task)) {
            throw exception(ErrorCodeConstants.TASK_NOT_EXISTS);
        }
        String processInstanceId = task.getProcessInstanceId();
        ProcessInstance processInstance = processInstanceService.getProcessInstance(processInstanceId);
        if (processInstance == null) {
            throw exception(ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS);
        }

        ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition(
                processInstance.getProcessDefinitionId());
        if (processDefinition == null) {
            throw exception(ErrorCodeConstants.PROCESS_DEFINITION_NOT_EXISTS);
        }
        List<NotifySendSingleToUserReqDTO> copyNotifyList = new ArrayList<>();
        List<CorpSendMessage> corpList = new ArrayList<CorpSendMessage>();
        List<BpmProcessInstanceCopyDO> copyList = new ArrayList<>();
        taskCopyUserDOList.forEach(taskCopyUserDO -> {
            AdminUserRespDTO userTenantIgnore = adminUserApi.getUserTenantIgnore(taskCopyUserDO.getId());
            NotifySendSingleToUserReqDTO notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(
                    taskCopyUserDO.getId(), reqDTO.getProcessInstanceId(),
                    "", detailUrl, BpmMessageEnum.BPM_COPY_INSTANCE_APPROVE.getTemplateCode(), templateParams,
                    NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_COPY.getValue(),
                    NotifyPriorityEnum.MEDIUM.getValue(), 0, userTenantIgnore.getTenantId());
            copyNotifyList.add(notifySendSingleToUserReqDTO);
            BpmProcessInstanceCopyDO copyDO = new BpmProcessInstanceCopyDO()
                    .setUserId(taskCopyUserDO.getId()).setStartUserId(Long.valueOf(processInstance.getStartUserId()))
                    .setProcessInstanceId(reqDTO.getProcessInstanceId()).setProcessInstanceName(reqDTO.getProcessInstanceName())
                    .setCategory(processDefinition.getCategory()).setTaskId(task.getId())
                    .setTaskName(task.getName()).setTenantId(userTenantIgnore.getTenantId());
            copyList.add(copyDO);
            CorpSendMessage corpSendMessage = new CorpSendMessage();
            WechatMessageSaveReq wechatMessageSaveReq = new WechatMessageSaveReq();
            AdminUserRespDTO promoter = adminUserApi.getUser(taskCopyUserDO.getId());
            String corpUserId = promoter.getCorpUserId() == null ? "" : promoter.getCorpUserId().toString();
            CorpWechatTextcard corpTextCard = new CorpWechatTextcard();
            corpTextCard.setTitle(CorpMsgUtil.TITLE_COPY);
            corpTextCard.setBtntxt(CorpMsgUtil.BTNTXT_DETAIL_NOTICE);
            corpTextCard.setUrl(String.format(BPM_DETAIL_URL, reqDTO.getProcessInstanceId(), 4, businessFormDO.getStatus()));
            corpSendMessage.setTouser(corpUserId);
            corpSendMessage.setTextcard(corpTextCard);
            wechatMessageSaveReq.setTitle(CorpMsgUtil.TITLE_COPY);
            wechatMessageSaveReq.setTenantName(tenant.getAbbreviation());
            wechatMessageSaveReq.setPkMessage(reqDTO.getProcessInstanceId());
            wechatMessageSaveReq.setPkMessage2("");
            wechatMessageSaveReq.setCorpUserId(corpUserId);
            wechatMessageSaveReq.setStartTenantId(tenant.getId());
            corpSendMessage.setWechatMessageSaveReq(wechatMessageSaveReq);
            corpList.add(corpSendMessage);

        });
        notifyMessageSendApi.sendSingleMessageToAdminByList(copyNotifyList);
        processInstanceCopyMapper.insertBatch(copyList);

        notifyMessageSendApi.sendCorpMessageList(corpList, copyNotifyList.get(0));


    }

    private void sendRejectMessageByType(BpmMessageSendWhenProcessInstanceRejectReqDTO reqDTO,
                                         Map<String, Object> templateParams) {
        BpmBusinessFormDO businessFormDO = businessFormService.selectOneByProcessInstanceId(reqDTO.getProcessInstanceId());
        AdminUserRespDTO user = adminUserApi.getUserTenantIgnore(businessFormDO.getUserId());
        AdminUserRespDTO assigneeUser = adminUserApi.getUserTenantIgnore(reqDTO.getStartUserId());
        TenantRespDTO tenant = tenantApi.getTenant(businessFormDO.getStartTenantId());
        ElderlyInfoReqVO elderlyInfo = null;
        NotifySendSingleToUserReqDTO notifySendSingleToUserReqDTO = null;
        String detailUrl = "";
        CorpSendMessage corpSendMessage = new CorpSendMessage();
        WechatMessageSaveReq wechatMessageSaveReq = new WechatMessageSaveReq();
        Integer notifyType = NotifyTypeEnum.NOTIFY_READ.getValue();
        switch (BpmBusinessTypeEnum.valueOf(businessFormDO.getType())) {
            case APPLY_ACCOMMODATION:
                elderlyInfo = bpmElderlyApi.getElderlyInfo(businessFormDO.getBusinessId2());
                templateParams.put("nickname", user.getNickname());
                templateParams.put("elderName", elderlyInfo.getElderName());
                detailUrl = getInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
                templateParams.put("detailUrl", detailUrl);
                notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getStartUserId(),
                        reqDTO.getProcessInstanceId(), "", detailUrl,
                        BpmMessageEnum.PROCESS_INSTANCE_REJECT.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), notifyType,
                        NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
                break;
            case APPLY_RETREAT:
                detailUrl = getInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
                elderlyInfo = bpmElderlyApi.getElderlyInfoByRetreatId(businessFormDO.getBusinessId());
                templateParams.put("nickname", user.getNickname());
                templateParams.put("elderName", elderlyInfo.getElderName());
                templateParams.put("detailUrl", detailUrl);
                notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getStartUserId(),
                        reqDTO.getProcessInstanceId(), "", detailUrl,
                        BpmMessageEnum.RETREAT_PROCESS_INSTANCE_REJECT.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), notifyType,
                        NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
                break;
            case BED_CHANGE:
                detailUrl = getInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
                elderlyInfo = bpmElderlyChangeApi.getElderlyInfoByChangeId(businessFormDO.getBusinessId());
                templateParams.put("nickname", user.getNickname());
                templateParams.put("elderName", elderlyInfo.getElderName());
                templateParams.put("detailUrl", detailUrl);
                notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getStartUserId(),
                        reqDTO.getProcessInstanceId(), "", detailUrl,
                        BpmMessageEnum.BED_CHANGE_PROCESS_INSTANCE_REJECT.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), notifyType,
                        NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
                break;
            case NURSE_CHANGE:
                detailUrl = getInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
                elderlyInfo = bpmElderlyChangeApi.getElderlyInfoByChangeId(businessFormDO.getBusinessId());
                templateParams.put("nickname", user.getNickname());
                templateParams.put("elderName", elderlyInfo.getElderName());
                templateParams.put("detailUrl", detailUrl);
                notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getStartUserId(),
                        reqDTO.getProcessInstanceId(), "", detailUrl,
                        BpmMessageEnum.NURSE_CHANGE_PROCESS_INSTANCE_REJECT.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), notifyType,
                        NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
                break;
            case CATERING_CHANGE:
                detailUrl = getInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
                elderlyInfo = bpmElderlyChangeApi.getElderlyInfoByChangeId(businessFormDO.getBusinessId());
                templateParams.put("nickname", user.getNickname());
                templateParams.put("elderName", elderlyInfo.getElderName());
                templateParams.put("detailUrl", detailUrl);
                notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getStartUserId(),
                        reqDTO.getProcessInstanceId(), "", detailUrl,
                        BpmMessageEnum.CATERING_CHANGE_PROCESS_INSTANCE_REJECT.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), notifyType,
                        NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
                break;
            case PRICE_CHANGE:
                detailUrl = getInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
                elderlyInfo = bpmElderlyChangeApi.getElderlyInfoByChangeId(businessFormDO.getBusinessId());
                templateParams.put("nickname", user.getNickname());
                templateParams.put("elderName", elderlyInfo.getElderName());
                templateParams.put("detailUrl", detailUrl);
                notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getStartUserId(),
                        reqDTO.getProcessInstanceId(), "", detailUrl,
                        BpmMessageEnum.PRICE_CHANGE_PROCESS_INSTANCE_REJECT.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), notifyType,
                        NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
                break;
            case TRANSFER_CHANGE:
                detailUrl = getInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
                elderlyInfo = bpmElderlyChangeApi.getElderlyInfoByChangeId(businessFormDO.getBusinessId());
                templateParams.put("nickname", user.getNickname());
                templateParams.put("elderName", elderlyInfo.getElderName());
                templateParams.put("detailUrl", detailUrl);
                notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getStartUserId(),
                        reqDTO.getProcessInstanceId(), "", detailUrl,
                        BpmMessageEnum.TRANSFER_CHANGE_PROCESS_INSTANCE_REJECT.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), notifyType,
                        NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
            case CHECK_IN:
                detailUrl = getInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
                elderlyInfo = bpmElderlyApi.getElderlyInfo(businessFormDO.getBusinessId2());
                templateParams.put("nickname", user.getNickname());
                templateParams.put("elderName", elderlyInfo.getElderName());
                templateParams.put("detailUrl", detailUrl);
                notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getStartUserId(),
                        reqDTO.getProcessInstanceId(), "", detailUrl,
                        BpmMessageEnum.CHECK_IN_PROCESS_INSTANCE_REJECT.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), notifyType,
                        NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
                break;
            case CHECK_IN_WAIT:
                detailUrl = getInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
                JSONObject checkInWaitInfo = bpmCheckInWaitApi.selectById(businessFormDO.getBusinessId2());
                templateParams.put("nickname", user.getNickname());
                templateParams.put("elderName", checkInWaitInfo.getString("elderName"));
                templateParams.put("detailUrl", detailUrl);
                notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getStartUserId(),
                        reqDTO.getProcessInstanceId(), "", detailUrl,
                        BpmMessageEnum.CHECK_IN_WAIT_PROCESS_INSTANCE_REJECT.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), notifyType,
                        NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
                break;
            default:
                break;
        }
        String corpUserId = assigneeUser.getCorpUserId() == null ? "" : assigneeUser.getCorpUserId().toString();
        CorpWechatTextcard corpTextCard = new CorpWechatTextcard();
        corpTextCard.setTitle(CorpMsgUtil.TITLE_REFUSE);
        corpTextCard.setBtntxt(CorpMsgUtil.BTNTXT_DETAIL_NOTICE);
        corpTextCard.setUrl(String.format(BPM_DETAIL_URL, reqDTO.getProcessInstanceId(), 1, businessFormDO.getStatus()));
        corpSendMessage.setTouser(corpUserId);
        corpSendMessage.setTextcard(corpTextCard);
        wechatMessageSaveReq.setTitle(CorpMsgUtil.TITLE_REFUSE);
        wechatMessageSaveReq.setPkMessage(reqDTO.getProcessInstanceId());
        wechatMessageSaveReq.setPkMessage2("");
        wechatMessageSaveReq.setCorpUserId(corpUserId);
        wechatMessageSaveReq.setTenantName(tenant.getAbbreviation());
        wechatMessageSaveReq.setTypeName(reqDTO.getProcessInstanceName());
        wechatMessageSaveReq.setReason(reqDTO.getReason());
        corpSendMessage.setWechatMessageSaveReq(wechatMessageSaveReq);

        notifyMessageSendApi.sendMessageAndCorpMessage(notifySendSingleToUserReqDTO, corpSendMessage);

    }

    private void sendTaskAssignedMessageByType(BpmMessageSendWhenTaskCreatedReqDTO reqDTO, Map<String, Object> templateParams,
                                               Integer approveMethod, Boolean startNodeFlag) {



        BpmBusinessFormDO businessFormDO = businessFormService.selectOneByProcessInstanceId(reqDTO.getProcessInstanceId());
        String detailUrl = "";
        AdminUserRespDTO user = adminUserApi.getUserTenantIgnore(businessFormDO.getUserId());
        AdminUserRespDTO assigneeUser = adminUserApi.getUserTenantIgnore(reqDTO.getAssigneeUserId());
        TenantRespDTO tenant = tenantApi.getTenant(businessFormDO.getStartTenantId());
        Long loginUserId = getLoginUserId();
        CorpSendMessage corpSendMessage = new CorpSendMessage();
        WechatMessageSaveReq wechatMessageSaveReq = new WechatMessageSaveReq();
        ElderlyInfoReqVO elderlyInfo = null;
        NotifySendSingleToUserReqDTO notifySendSingleToUserReqDTO = null;
        if (BpmBusinessTypeEnum.APPLY_ACCOMMODATION.getValue().equals(businessFormDO.getType())) {
            elderlyInfo = bpmElderlyApi.getElderlyInfo(businessFormDO.getBusinessId2());
            templateParams.put("nickname", user.getNickname());
            templateParams.put("elderName", elderlyInfo.getElderName());
            detailUrl = getInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
            templateParams.put("detailUrl", detailUrl);
            NotieBusinessTypeEnum.BPM.getValue();
            notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getAssigneeUserId(),
                    reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), detailUrl,
                    BpmMessageEnum.TASK_ASSIGNED.getTemplateCode(), templateParams,
                    NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                    NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
            if (reqDTO.getStartUserId().equals(loginUserId)) {
                notifyMessageSendApi.sendSingleMessageToAdminByDTO(BpmMessageConvert.INSTANCE.messageConvert(loginUserId,
                        reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), detailUrl,
                        BpmMessageEnum.TASK_ASSIGNED.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                        NotifyPriorityEnum.MEDIUM.getValue(), 1, assigneeUser.getTenantId()));
            }

        }

        if (BpmBusinessTypeEnum.APPLY_RETREAT.getValue().equals(businessFormDO.getType())) {
            elderlyInfo = bpmElderlyApi.getElderlyInfoByRetreatId(businessFormDO.getBusinessId());
            templateParams.put("nickname", user.getNickname());
            templateParams.put("elderName", elderlyInfo.getElderName());
            detailUrl = getInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
            templateParams.put("detailUrl", detailUrl);
            notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getAssigneeUserId(),
                    reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), detailUrl,
                    BpmMessageEnum.RETREAT_TASK_ASSIGNED.getTemplateCode(), templateParams,
                    NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                    NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
            if (reqDTO.getStartUserId().equals(loginUserId)) {
                notifyMessageSendApi.sendSingleMessageToAdminByDTO(BpmMessageConvert.INSTANCE.messageConvert(loginUserId,
                        reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), detailUrl,
                        BpmMessageEnum.RETREAT_TASK_ASSIGNED.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                        NotifyPriorityEnum.MEDIUM.getValue(), 1, assigneeUser.getTenantId()));
            }

        }

        if (BpmBusinessTypeEnum.BED_CHANGE.getValue().equals(businessFormDO.getType())) {
            elderlyInfo = bpmElderlyChangeApi.getElderlyInfoByChangeId(businessFormDO.getBusinessId());
            templateParams.put("nickname", user.getNickname());
            templateParams.put("elderName", elderlyInfo.getElderName());
            detailUrl = getInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
            templateParams.put("detailUrl", detailUrl);
            notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getAssigneeUserId(),
                    reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), detailUrl,
                    BpmMessageEnum.BED_CHANGE_PROCESS_TASK_ASSIGNED.getTemplateCode(), templateParams,
                    NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                    NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
            if (reqDTO.getStartUserId().equals(loginUserId)) {
                notifyMessageSendApi.sendSingleMessageToAdminByDTO(BpmMessageConvert.INSTANCE.messageConvert(loginUserId,
                        reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), detailUrl,
                        BpmMessageEnum.BED_CHANGE_PROCESS_TASK_ASSIGNED.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                        NotifyPriorityEnum.MEDIUM.getValue(), 1, assigneeUser.getTenantId()));
            }
        }

        if (BpmBusinessTypeEnum.NURSE_CHANGE.getValue().equals(businessFormDO.getType())) {
            elderlyInfo = bpmElderlyChangeApi.getElderlyInfoByChangeId(businessFormDO.getBusinessId());
            templateParams.put("nickname", user.getNickname());
            templateParams.put("elderName", elderlyInfo.getElderName());
            detailUrl = getInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
            templateParams.put("detailUrl", detailUrl);
            notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getAssigneeUserId(),
                    reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), detailUrl,
                    BpmMessageEnum.NURSE_CHANGE_PROCESS_TASK_ASSIGNED.getTemplateCode(), templateParams,
                    NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                    NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
            if (reqDTO.getStartUserId().equals(loginUserId) && !reqDTO.getStartUserId().equals(reqDTO.getAssigneeUserId()) && !reqDTO.getStartNodeFlag()) {
                notifyMessageSendApi.sendSingleMessageToAdminByDTO(BpmMessageConvert.INSTANCE.messageConvert(loginUserId,
                        reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), detailUrl,
                        BpmMessageEnum.NURSE_CHANGE_PROCESS_TASK_ASSIGNED.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                        NotifyPriorityEnum.MEDIUM.getValue(), 1, assigneeUser.getTenantId()));
            }

        }

        if (BpmBusinessTypeEnum.CATERING_CHANGE.getValue().equals(businessFormDO.getType())) {
            elderlyInfo = bpmElderlyChangeApi.getElderlyInfoByChangeId(businessFormDO.getBusinessId());
            templateParams.put("nickname", user.getNickname());
            templateParams.put("elderName", elderlyInfo.getElderName());
            detailUrl = getInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
            templateParams.put("detailUrl", detailUrl);
            notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getAssigneeUserId(),
                    reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), detailUrl,
                    BpmMessageEnum.CATERING_CHANGE_PROCESS_TASK_ASSIGNED.getTemplateCode(), templateParams,
                    NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                    NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
            if (reqDTO.getStartUserId().equals(loginUserId)) {
                notifyMessageSendApi.sendSingleMessageToAdminByDTO(BpmMessageConvert.INSTANCE.messageConvert(loginUserId,
                        reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), detailUrl,
                        BpmMessageEnum.CATERING_CHANGE_PROCESS_TASK_ASSIGNED.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                        NotifyPriorityEnum.MEDIUM.getValue(), 1, assigneeUser.getTenantId()));
            }
        }

        if (BpmBusinessTypeEnum.PRICE_CHANGE.getValue().equals(businessFormDO.getType())) {
            elderlyInfo = bpmElderlyChangeApi.getElderlyInfoByChangeId(businessFormDO.getBusinessId());
            templateParams.put("nickname", user.getNickname());
            templateParams.put("elderName", elderlyInfo.getElderName());
            detailUrl = getInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
            templateParams.put("detailUrl", detailUrl);
            notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getAssigneeUserId(),
                    reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), detailUrl,
                    BpmMessageEnum.PRICE_CHANGE_PROCESS_TASK_ASSIGNED.getTemplateCode(), templateParams,
                    NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                    NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
            if (reqDTO.getStartUserId().equals(loginUserId)) {
                notifyMessageSendApi.sendSingleMessageToAdminByDTO(BpmMessageConvert.INSTANCE.messageConvert(loginUserId,
                        reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), detailUrl,
                        BpmMessageEnum.PRICE_CHANGE_PROCESS_TASK_ASSIGNED.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                        NotifyPriorityEnum.MEDIUM.getValue(), 1, assigneeUser.getTenantId()));
            }
        }

        if (BpmBusinessTypeEnum.TRANSFER_CHANGE.getValue().equals(businessFormDO.getType())) {
            elderlyInfo = bpmElderlyChangeApi.getElderlyInfoByChangeId(businessFormDO.getBusinessId());
            templateParams.put("nickname", user.getNickname());
            templateParams.put("elderName", elderlyInfo.getElderName());
            detailUrl = getInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
            templateParams.put("detailUrl", detailUrl);
            notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getAssigneeUserId(),
                    reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), detailUrl,
                    BpmMessageEnum.TRANSFER_CHANGE_PROCESS_TASK_ASSIGNED.getTemplateCode(), templateParams,
                    NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                    NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
            if (reqDTO.getStartUserId().equals(loginUserId)) {
                notifyMessageSendApi.sendSingleMessageToAdminByDTO(BpmMessageConvert.INSTANCE.messageConvert(loginUserId,
                        reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), detailUrl,
                        BpmMessageEnum.TRANSFER_CHANGE_PROCESS_TASK_ASSIGNED.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                        NotifyPriorityEnum.MEDIUM.getValue(), 1, assigneeUser.getTenantId()));
            }
        }

        if (BpmBusinessTypeEnum.CHECK_IN.getValue().equals(businessFormDO.getType())) {
            // TODO 办理入住
            elderlyInfo = bpmElderlyApi.getElderlyInfo(businessFormDO.getBusinessId2());
            templateParams.put("nickname", user.getNickname());
            templateParams.put("elderName", elderlyInfo.getElderName());
            detailUrl = getInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
            templateParams.put("detailUrl", detailUrl);
            notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getAssigneeUserId(),
                    reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), detailUrl,
                    BpmMessageEnum.CHECK_IN_PROCESS_TASK_ASSIGNED.getTemplateCode(), templateParams,
                    NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                    NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
            if (reqDTO.getStartUserId().equals(loginUserId)) {
                notifyMessageSendApi.sendSingleMessageToAdminByDTO(BpmMessageConvert.INSTANCE.messageConvert(loginUserId,
                        reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), detailUrl,
                        BpmMessageEnum.CHECK_IN_PROCESS_TASK_ASSIGNED.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                        NotifyPriorityEnum.MEDIUM.getValue(), 1, assigneeUser.getTenantId()));
            }
        }

        if (BpmBusinessTypeEnum.CHECK_IN_WAIT.getValue().equals(businessFormDO.getType())) {
            JSONObject checkInWaitInfo = bpmCheckInWaitApi.selectById(businessFormDO.getBusinessId2());
            templateParams.put("nickname", user.getNickname());
            templateParams.put("elderName", checkInWaitInfo.getString("elderName"));
            detailUrl = getInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
            templateParams.put("detailUrl", detailUrl);
            notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getAssigneeUserId(),
                    reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), detailUrl,
                    BpmMessageEnum.CHECK_IN_WAIT_PROCESS_TASK_ASSIGNED.getTemplateCode(), templateParams,
                    NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                    NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
            if (reqDTO.getStartUserId().equals(loginUserId)) {
                notifyMessageSendApi.sendSingleMessageToAdminByDTO(BpmMessageConvert.INSTANCE.messageConvert(loginUserId,
                        reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), detailUrl,
                        BpmMessageEnum.CHECK_IN_WAIT_PROCESS_TASK_ASSIGNED.getTemplateCode(), templateParams,
                        NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                        NotifyPriorityEnum.MEDIUM.getValue(), 1, assigneeUser.getTenantId()));
            }
        }

        if (null == approveMethod && startNodeFlag) {
            elderlyInfo = bpmElderlyApi.getElderlyInfo(businessFormDO.getBusinessId2());
            templateParams.put("nickname", user.getNickname());
            templateParams.put("elderName", elderlyInfo.getElderName());
            detailUrl = getInstanceDetailUrl(reqDTO.getProcessInstanceId()) + "&businessId=" + businessFormDO.getBusinessId();
            templateParams.put("detailUrl", detailUrl);
            notifySendSingleToUserReqDTO = BpmMessageConvert.INSTANCE.messageConvert(reqDTO.getAssigneeUserId(),
                    reqDTO.getProcessInstanceId(), reqDTO.getTaskId(), detailUrl,
                    BpmMessageEnum.PROCESS_INSTANCE_BACK.getTemplateCode(), templateParams,
                    NotieBusinessTypeEnum.BPM.getValue(), NotifyTypeEnum.NOTIFY_TODO.getValue(),
                    NotifyPriorityEnum.MEDIUM.getValue(), 0, assigneeUser.getTenantId());
            notifyMessageSendApi.sendSingleMessageToAdminByDTO(notifySendSingleToUserReqDTO);
            return;
        }

        String corpUserId = assigneeUser.getCorpUserId() == null ? "" : assigneeUser.getCorpUserId().toString();
        CorpWechatTextcard corpTextCard = new CorpWechatTextcard();
        corpTextCard.setTitle(CorpMsgUtil.TITLE_HANDLED);
        corpTextCard.setBtntxt(CorpMsgUtil.BTNTXT_DETAIL_HANDLED);
        corpTextCard.setUrl(String.format(BPM_DETAIL_URL, reqDTO.getProcessInstanceId(), 1, businessFormDO.getStatus()));
        corpSendMessage.setTouser(corpUserId);
        corpSendMessage.setTextcard(corpTextCard);
        wechatMessageSaveReq.setTitle(CorpMsgUtil.TITLE_HANDLED);
        wechatMessageSaveReq.setPkMessage(reqDTO.getProcessInstanceId());
        wechatMessageSaveReq.setPkMessage2(reqDTO.getTaskId());
        wechatMessageSaveReq.setCorpUserId(corpUserId);
        wechatMessageSaveReq.setStartTenantId(tenant.getId());
        wechatMessageSaveReq.setTenantName(tenant.getAbbreviation());
        wechatMessageSaveReq.setTypeName(reqDTO.getProcessInstanceName());
        wechatMessageSaveReq.setApplyTime(DateUtils.localDateTimeToStr(businessFormDO.getCreateTime()));
        corpSendMessage.setWechatMessageSaveReq(wechatMessageSaveReq);
        notifyMessageSendApi.sendMessageAndCorpMessage(notifySendSingleToUserReqDTO, corpSendMessage);
    }


    private String getProcessInstanceDetailUrl(String taskId) {
        return webProperties.getAdminUi().getUrl() + "/bpm/process-instance/detail?id=" + taskId;
    }

    private String getInstanceDetailUrl(String taskId) {
        return "/bpm/process-instance/detail?id=" + taskId;
    }

}
