package com.ningdatech.pmapi.scheduler.listener;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.cache.model.cache.CacheKey;
import com.ningdatech.cache.repository.CachePlusOps;
import com.ningdatech.pmapi.common.constant.BizConst;
import com.ningdatech.pmapi.common.helper.UserInfoHelper;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.projectlib.model.entity.ProjectInst;
import com.ningdatech.pmapi.projectlib.service.IProjectInstService;
import com.ningdatech.pmapi.projectlib.service.IProjectService;
import com.ningdatech.pmapi.staging.enums.MsgTypeEnum;
import com.ningdatech.pmapi.sys.manage.NoticeManage;
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO;
import com.wflow.bean.entity.WflowCcTasks;
import com.wflow.service.WflowCcTasksService;
import com.wflow.workflow.notify.event.CcTaskEvent;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.HistoryService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.time.Duration;
import java.util.List;
import java.util.Objects;
import static com.ningdatech.pmapi.todocenter.constant.WorkNoticeConstant.CC_MSG_TEMPLATE;

/**
 * 抄送事件 事件监听
 *
 * @author ZPF
 * @return
 * @since 2023/04/14 14:19
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class CcTaskListener {
    private final IProjectInstService projectInstService;

    private final HistoryService historyService;
    private final IProjectService projectService;
    private final NoticeManage noticeManage;

    private final WflowCcTasksService ccTasksService;

    private final CachePlusOps cachePlusOps;

    private final UserInfoHelper userInfoHelper;

    private static final String DUP_KEY = "ccTasks";
    private static final String NODE = "node:";

    @Async
    @EventListener
    public void onApplicationEvent(CcTaskEvent event) throws InterruptedException {
        log.info("进入抄送人任务 事件监听!{}", JSON.toJSONString(event));
        String instCode = event.getInstCode();
        String processDefinitionId = event.getProcessDefinitionId();
        String nodeId = event.getNodeId();
        String taskId = event.getTaskId();

        //这里 redis 处理一下 1分钟处理同一 nodeId 一次
        if (cachePlusOps.get(NODE + nodeId + DUP_KEY) != null) {
            log.info("一分钟只能处理该nodeId一次!{}", nodeId);
            return;
        }

        //1分钟
        CacheKey key = new CacheKey();
        key.setKey(NODE + nodeId + DUP_KEY);
        key.setExpire(Duration.ofMinutes(1));
        cachePlusOps.set(key, nodeId);

        //睡3秒 让数据库 生成抄送数据先
        Thread.sleep(3000);

        log.info("instCode :{},nodeId :{}",instCode, nodeId);
        //1.去查找 项目实例关系表
        List<WflowCcTasks> tasks = ccTasksService.list(Wrappers.lambdaQuery(WflowCcTasks.class)
                .eq(WflowCcTasks::getInstanceId, instCode)
                .eq(WflowCcTasks::getNodeId, nodeId));

        if (Objects.isNull(tasks)) {
            return;
        }

        log.info("tasks :{}",tasks.size());

        //有可能 一个节点 有多个用户抄送
        tasks.stream().forEach(task -> {
            log.info("cc tasks :{}",JSON.toJSONString(tasks));

            HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(instCode)
                    .singleResult();

            log.info("instance :{}",JSON.toJSONString(instance));

            ProjectInst projectInst = projectInstService.getOne(Wrappers.lambdaQuery(ProjectInst.class)
                    .eq(ProjectInst::getInstCode, instCode)
                    .last(BizConst.LIMIT_1));

            log.info("projectInst :{}",JSON.toJSONString(projectInst));

            if(Objects.isNull(projectInst) || Objects.isNull(instance)){
                return;
            }
            Long projectId = projectInst.getProjectId();
            Project project = projectService.getNewProject(projectId);

            UserFullInfoDTO user = userInfoHelper.getUserFullInfoByEmployeeCode(task.getUserId());

            //发送消息
            noticeManage.sendNotice(task.getUserId(),Objects.nonNull(user)? user.getUserId() : 93L,project,instance.getProcessDefinitionName(),
                    CC_MSG_TEMPLATE, MsgTypeEnum.PROJECT_REVIEW_CC);
        });
    }
}