package com.hz.pm.api.scheduler.listener;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hz.pm.api.common.model.constant.BizConst;
import com.hz.pm.api.common.statemachine.util.StateMachineUtil;
import com.hz.pm.api.projectlib.model.entity.Project;
import com.hz.pm.api.projectlib.model.entity.ProjectInst;
import com.hz.pm.api.projectlib.service.IProjectInstService;
import com.hz.pm.api.projectlib.service.IProjectService;
import com.wflow.workflow.notify.event.ProcessStartEvent;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.HistoryService;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * 工作流开始 事件监听
 *
 * @author ZPF
 * @return
 * @since 2023/04/14 14:19
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ProcessStartListener {
    private final TaskService taskService;
    private final HistoryService historyService;
    private final IProjectInstService projectInstService;

    private final IProjectService projectService;

    private final StateMachineUtil stateMachineUtil;

    @Async
    @EventListener
    public void onApplicationEvent(ProcessStartEvent event) {
        log.info("进入工作流开始 事件监听!{}", event.getInstCode());
        String instCode = event.getInstCode();

        log.info("instCode:{}", instCode);

        //休息3秒
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            log.error("流程开起异常：", e);
            Thread.currentThread().interrupt();
        }

        //1.去查找 项目实例关系表
        ProjectInst projectInst = projectInstService.getOne(Wrappers.lambdaQuery(ProjectInst.class)
                .eq(ProjectInst::getInstCode, instCode)
                .last(BizConst.LIMIT_1));

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

        List<Task> tasks = taskService.createTaskQuery()
                .processInstanceId(instCode)
                .active()
                .list();

        List<HistoricTaskInstance> historyTasks = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(instCode)
                .finished()
                .list();

        //如果 是没有审批任务的话 就需要 去调用状态机 进入下一个阶段
        if (CollUtil.isEmpty(tasks) && CollUtil.isEmpty(historyTasks)) {
            //如果真的没有实时任务和历史任务 那么说明 该项目没有人审批 需要去调用状态机
            Long projectId = projectInst.getProjectId();
            Project project = projectService.getNewProject(projectId);
            stateMachineUtil.pass(project);
            project.setUpdateOn(LocalDateTime.now());
            projectService.updateById(project);
        }
    }
}