package com.casic.missiles.service.listeners.flowable;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.casic.missiles.dto.flowable.NotifyEventStatusDTO;
import com.casic.missiles.enums.notifyevent.AwareActionStatusEnum;
import com.casic.missiles.enums.system.ApplyFromIdEnum;
import com.casic.missiles.enums.system.ApprovalStatusEnum;
import com.casic.missiles.mapper.system.SystemFlowFormMapper;
import com.casic.missiles.mapper.workbench.WorkbenchApprovalMessageMapper;
import com.casic.missiles.model.system.SystemFlowForm;
import com.casic.missiles.model.workbench.WorkbenchApprovalMessage;
import com.casic.missiles.modular.system.dao.UserMapper;
import com.casic.missiles.modular.system.model.User;
import com.casic.missiles.service.listeners.NotifyEventPostProcessor;
import com.casic.missiles.utils.SpringContextUtil;
import com.casic.missiles.utils.WebSocket;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.flowable.engine.repository.ProcessDefinition;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

@Slf4j
@Component
public class ProcessUpdateStateListener implements ExecutionListener {

    @Override
    @Transactional
    public void notify(DelegateExecution execution) {
        RepositoryService repositoryService = SpringContextUtil.getBean(RepositoryService.class);
        RuntimeService runtimeService = SpringContextUtil.getBean(RuntimeService.class);
        SystemFlowFormMapper flowFormMapper = SpringContextUtil.getBean(SystemFlowFormMapper.class);
        System.out.println("审批通过触发监听器:" + execution);
        ProcessDefinition processDefinition = repositoryService.getProcessDefinition(execution.getProcessDefinitionId());
        QueryWrapper<SystemFlowForm> wrapper = new QueryWrapper<>();
        wrapper.eq("pro_def_id", processDefinition.getKey());
        wrapper.eq("is_del", 0);
        // 查出流程定义信息
        SystemFlowForm systemFlowForm = flowFormMapper.selectOne(wrapper);
        String id = execution.getProcessInstanceBusinessKey();
        AwareActionStatusEnum notifyActionStatusEnum = AwareActionStatusEnum.ACTION_STATUS_MAP.getActionStatusMap().get(systemFlowForm.getFormId());
        if (null != notifyActionStatusEnum) {
            NotifyEventStatusDTO notifyEventStatusDTO = NotifyEventStatusDTO.builder()
                    .id(id)
                    .status(notifyActionStatusEnum.getStatus()).build();
            NotifyEventPostProcessor postProcessor = SpringContextUtil.getBean(notifyActionStatusEnum.getActionBeanName());
            if (postProcessor != null) {
                postProcessor.doHandleNotifyEvent(notifyEventStatusDTO);
            }
        }
        //设置通过状态为已通过
        runtimeService.updateBusinessStatus(execution.getProcessInstanceId(), ApprovalStatusEnum.PASSED);
        //审批通过，通知发起人
        sendMessageAndSocket(execution, systemFlowForm);
    }

    private void sendMessageAndSocket(DelegateExecution execution, SystemFlowForm systemFlowForm) {
        JSONObject jsonObject = JSONObject.parseObject(systemFlowForm.getFlowDef());
        JSONObject workFlowDef = jsonObject.getJSONObject("workFlowDef");
        Integer noticeStarter = workFlowDef.getInteger("noticeStarter");
        if (!Objects.isNull(noticeStarter) && 1 == noticeStarter) {
            Long rootId = Long.valueOf(String.valueOf(execution.getVariable("root")));
            String formName = jsonObject.getString("formName");
            String formId = systemFlowForm.getFormId();
            //总工作台中需要展示所有业务的用户待审批的列表（查询每个业务的待审批进行组合）
            //每个业务和前端定一个type（用formId即可，前提要保证流程定义和formId为一对一关系），用于前端页面跳转
            WorkbenchApprovalMessageMapper approvalMessageMapper = SpringContextUtil.getBean(WorkbenchApprovalMessageMapper.class);
            UserMapper userMapper = SpringContextUtil.getBean(UserMapper.class);
            User user = userMapper.selectById(rootId);
            WorkbenchApprovalMessage approvalMessage = new WorkbenchApprovalMessage();
            approvalMessage.setNoticeId(rootId);
            approvalMessage.setNoticeDeptId(user.getDeptId());
            approvalMessage.setBusinessId(execution.getProcessInstanceBusinessKey());
            approvalMessage.setProcessId(execution.getProcessInstanceId());
            approvalMessage.setMessageTitle("结果通知");
            approvalMessage.setMessageSourceModule(ApplyFromIdEnum.getSourceByCode(formId));
            approvalMessage.setMessageContent(formName);
            approvalMessage.setFormId(formId);
            approvalMessage.setCreateTime(DateUtil.now());
            if (approvalMessageMapper.insert(approvalMessage) < 0) {
                log.error("审批通过，通知发起人失败，approvalMessage：{}", approvalMessage.toString());
            }else {
                log.info("审批通过，插入数据库成功，approvalMessage：{}", approvalMessage.toString());
                //websocket消息推送
                WebSocket webSocket = SpringContextUtil.getBean(WebSocket.class);
                webSocket.sendOneMessage(String.valueOf(rootId), JSONObject.toJSONString(approvalMessage));
            }
        }
    }

}
