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

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.oa.BpmOAWorkTaskDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
import cn.iocoder.yudao.module.bpm.enums.message.BpmMessageEnum;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
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.oa.BpmOAWorkTaskService;
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
import cn.iocoder.yudao.module.system.api.subscribe.SubscribeMessageSendApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

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

    @Resource
    private AdminUserApi userApi;

    @Resource
    private NotifyMessageSendApi notifyMessageSendApi;

    @Resource
    private SubscribeMessageSendApi subscribeMessageSendApi;

    @Resource
    private WebProperties webProperties;

    @Resource
    @Lazy // 解决循环依赖
    private BpmProcessInstanceService bpmProcessInstanceService;

    @Resource
    private BpmOAWorkTaskService workTaskService;

    @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.getSmsTemplateCode(), templateParams));

        //发送站内信息
        notifyMessageSendApi.sendSingleMessageToAdmin(BpmMessageConvert.INSTANCE.convert1(reqDTO.getStartUserId(),
                BpmMessageEnum.PROCESS_INSTANCE_APPROVE.getSmsTemplateCode(), templateParams));

        //发送审批结果通知至微信
        String openId = getUserOpenId(reqDTO.getStartUserId());
        if (openId != null) {

            // 获得任务分配数据
            BpmOAWorkTaskDO workTaskDO = workTaskService.getWorkTaskByProcessInstanceId(reqDTO.getProcessInstanceId());
            if (workTaskDO != null) {

                String nickName = userApi.getUser(workTaskDO.getReceiverUserId()).getCheckedData().getNickname();

                subscribeMessageSendApi.sendWorkLogComment(BpmMessageConvert.INSTANCE.convertWorkTask(
                        openId, reqDTO.getProcessInstanceName(), workTaskDO, nickName, reqDTO.getCreateTime(),
                        "formal", true));
            }else {

                subscribeMessageSendApi.sendApprovalResultNotification(
                        BpmMessageConvert.INSTANCE.convertApprovalResultNotification(
                                openId, reqDTO.getProcessInstanceName(), reqDTO.getCreateTime(), "通过", reqDTO.getReason(),
                                reqDTO.getProcessInstanceId(),
                                /**
                                 * 跳转小程序类型：developer为开发版；trial为体验版；formal为正式版；默认为正式版
                                 */
                                "formal"));
            }
        }

        //当流程全部审批通过
        BpmProcessInstanceExtDO processInstance = bpmProcessInstanceService.getProcessInstanceDO(reqDTO.getProcessInstanceId());
        if (processInstance.getResult().equals(BpmProcessInstanceResultEnum.APPROVE.getResult())) {

            //获取抄送用户ID
            String ccIDs = processInstance.getCcids();
            if (ccIDs != null && !ccIDs.isEmpty()) {

                Pattern pattern = Pattern.compile("\\[(\\d+)]");
                Matcher matcher = pattern.matcher(ccIDs);
                while (matcher.find()) {
                    String ccID = matcher.group(1);
                    String ccOpenId = getUserOpenId(Long.valueOf(ccID));

                    //发送抄送信息至微信
                    if (ccOpenId != null) {
                        subscribeMessageSendApi.sendApprovalResultNotification(
                                BpmMessageConvert.INSTANCE.convertApprovalResultNotification(
                                        ccOpenId, reqDTO.getProcessInstanceName(), reqDTO.getCreateTime(), "抄送", reqDTO.getReason(),
                                        reqDTO.getProcessInstanceId(),
                                        /**
                                         * 跳转小程序类型：developer为开发版；trial为体验版；formal为正式版；默认为正式版
                                         */
                                        "formal"));
                    }
                }
            }
        }
    }

    @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.getSmsTemplateCode(), templateParams));
        notifyMessageSendApi.sendSingleMessageToAdmin(BpmMessageConvert.INSTANCE.convert1(
                reqDTO.getStartUserId(), BpmMessageEnum.PROCESS_INSTANCE_REJECT.getSmsTemplateCode(), templateParams));

//        //发送审批结果通知
        String openId = getUserOpenId(reqDTO.getStartUserId());
        if (openId != null) {
            subscribeMessageSendApi.sendApprovalResultNotification(
                    BpmMessageConvert.INSTANCE.convertApprovalResultNotification(
                            openId, reqDTO.getProcessInstanceName(), reqDTO.getCreateTime(), "不通过", reqDTO.getReason(),
                            reqDTO.getProcessInstanceId(),
                            /**
                             * 跳转小程序类型：developer为开发版；trial为体验版；formal为正式版；默认为正式版
                             */
                            "formal"));
        }

    }

    @Override
    public void sendMessageWhenTaskAssigned(BpmMessageSendWhenTaskCreatedReqDTO reqDTO) {
        //任务分配
        Long startUserId = reqDTO.getStartUserId();         //流程发起人
        Long assigneeUserId = reqDTO.getAssigneeUserId();  //任务审批人
        String taskName = reqDTO.getTaskName();
        //如果流程发起人和任务审批是同一个人， 那么不发送站内信，否则就发送
        if (!assigneeUserId.toString().equals(startUserId.toString())) {
            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.getSmsTemplateCode(), templateParams));
            //站内信
            notifyMessageSendApi.sendSingleMessageToAdmin(BpmMessageConvert.INSTANCE.convert1(
                    reqDTO.getAssigneeUserId(), BpmMessageEnum.TASK_ASSIGNED.getSmsTemplateCode(), templateParams));

            //微信小程序订阅消息
            //发送OA流程待办提醒
            String openId = getUserOpenId(assigneeUserId); //只有在微信小程序登陆过用户才会有openid
            if (openId != null) {

                // 获得任务分配数据
                BpmOAWorkTaskDO workTaskDO = workTaskService.getWorkTaskByProcessInstanceId(reqDTO.getProcessInstanceId());
                if (workTaskDO != null) {

                    subscribeMessageSendApi.sendWorkLogComment(BpmMessageConvert.INSTANCE.convertWorkTask(
                            openId, reqDTO.getProcessInstanceName(), workTaskDO, reqDTO.getStartUserNickname(), reqDTO.getCreateTime(),
                            "formal", false));
                }else {

                    subscribeMessageSendApi.sendProcessToDoReminder(BpmMessageConvert.INSTANCE.convertProcessToDoReminder(
                            openId, reqDTO.getProcessInstanceName(), reqDTO.getStartUserNickname(), reqDTO.getCreateTime(), reqDTO.getSchedule(),
                            reqDTO.getProcessInstanceId(),
                            "formal"));
                }
            }
        }
    }

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

    @Resource
    private AdminUserApi adminUserApi;

    private String getUserOpenId(Long userId) {
        AdminUserRespDTO adminUserRespDTO = adminUserApi.getUser(userId).getData();

        return adminUserRespDTO.getOpenId();
    }
}
