package com.ningdatech.pmapi.instance;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.pmapi.AppTests;
import com.ningdatech.pmapi.common.constant.BizConst;
import com.ningdatech.pmapi.projectlib.manage.ProjectLibManage;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.projectlib.model.entity.ProjectInst;
import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq;
import com.ningdatech.pmapi.projectlib.service.IProjectInstService;
import com.wflow.workflow.bean.dto.TodoCenterListReqDTO;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.runtime.ActivityInstance;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.service.history.NativeHistoricTaskInstanceQuery;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Classname InstanceTest
 * @Description
 * @Date 2023/2/16 14:44
 * @Author PoffyZhang
 */
@Slf4j
public class InstanceTest extends AppTests {

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private ProjectLibManage projectLibManage;

    @Autowired
    private IProjectInstService projectInstService;

    @Test
    public void test() {
        String instanceId = "896fa188-96d8-11ed-9539-e2d4e8f16b2f";
        Object user = runtimeService.getVariable(instanceId,
                "owner");
        System.out.println(JSON.toJSONString(user));
    }

    @Test
    public void testHistory() {
        //如果有已经被审核过的 节点
        List<HistoricActivityInstance> finished = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId("085af7ef-d133-11ed-a3f6-02426daa406d").finished()
                .activityType("userTask")
                .orderByHistoricActivityInstanceEndTime().asc().list();
        HistoricActivityInstance historicActivityInstance = finished.get(0);
        System.out.println(finished);
    }

    @Test
    public void testRuntime() {
        //如果有已经被审核过的 节点
        List<ActivityInstance> userTask = runtimeService.createActivityInstanceQuery()
                .processInstanceId("1709ebe3-d148-11ed-9351-02426daa406d")
                .activityType("userTask")
                .orderByActivityInstanceStartTime().asc().list();
        System.out.println(userTask);
    }

    @Test
    public void testTodo() {
        String employeeCode = "GE_e9d5c7917acd4eeea04ff2a9454af62e";
        // 查出项目库项目
        ProjectListReq projectListReq = new ProjectListReq();
        List<Project> projects = projectLibManage.projectList(projectListReq);
        Map<Long, Project> projectsMap = projects.stream().collect(Collectors.toMap(Project::getId, v -> v));
        // 再查出项目关联的流程实例ID
        List<Long> projectIdList = projects.stream().map(Project::getId).collect(Collectors.toList());
        if (CollUtil.isEmpty(projectIdList)) {
            System.out.println("没有项目");
            return;
        }
        List<ProjectInst> projectInstList = projectInstService.list(Wrappers.lambdaQuery(ProjectInst.class)
                .in(ProjectInst::getProjectId, projectIdList)
                .orderByDesc(ProjectInst::getProjectId));
        Map<String, Project> projectInfoMap = projectInstList.stream().collect(Collectors.toMap(ProjectInst::getInstCode, p -> projectsMap.get(p.getProjectId())));
        List<String> instCodes = projectInstList.stream().map(ProjectInst::getInstCode).collect(Collectors.toList());

        // 查出用户工作流
        TodoCenterListReqDTO req = new TodoCenterListReqDTO();
        req.setEmployeeCode(employeeCode);
        req.setInstCodes(instCodes);

        // 自定义sql查询所有已办的任务实例
        String nativeSql = "SELECT ht.* FROM act_hi_taskinst ht WHERE assignee_ = '" + employeeCode +
                "' and  end_time_ is not NULL";
        NativeHistoricTaskInstanceQuery taskInstanceQuery =
                historyService.createNativeHistoricTaskInstanceQuery().sql(nativeSql);
        List<HistoricTaskInstance> taskInstances = taskInstanceQuery.list();

        Set<String> set = new HashSet<>();
        List<HistoricTaskInstance> taskInstanceList = taskInstances.stream()
                .filter(t -> instCodes.contains(t.getProcessInstanceId()))
                .sorted(Comparator.comparing(HistoricTaskInstance::getEndTime)).collect(Collectors.toList())
                .stream()
                .filter(v -> set.add(v.getProcessInstanceId()))
                .collect(Collectors.toList());

        System.out.println(taskInstanceList.size());
    }

    @Test
    public void test2() {
        // 获取节点处理结果
//        Map<String, ProcessHandlerEnum> varMap = historyService.createHistoricVariableInstanceQuery()
//                .processInstanceId("e99fe24c-d21c-11ed-af5d-02426daa406d")
//                .variableNameLike("approve_%")
//                .list().stream()
//                .collect(Collectors.toMap(HistoricVariableInstance::getVariableName, v -> (ProcessHandlerEnum) v.getValue()));
        runtimeService.removeVariable("564102ce-d1ff-11ed-b694-02424b2b849f", "approve_7d2a191a-d1ff-11ed-b694-02424b2b849f");
        System.out.println(1);
    }

    @Test
    public void usageTimeStat() {
        // 查询所有已完成的流程实例
        List<HistoricProcessInstance> processInstanceList = historyService.createHistoricProcessInstanceQuery()
                .orderByProcessInstanceStartTime()
                .desc()
                .finished()
                .list();

        // 统计每个流程实例的审批耗时
        for (HistoricProcessInstance processInstance : processInstanceList) {
            System.out.println("流程实例ID：" + processInstance.getId());
            System.out.println("流程开始时间：" + processInstance.getStartTime());
            System.out.println("流程结束时间：" + processInstance.getEndTime());
            System.out.println("流程耗时（ms）：" + processInstance.getDurationInMillis() / 1000);
            System.out.println("================================================================");
        }
    }

    @Test
    public void test4(){
        String nodeId = "node_64d1bc4694fc85e4dd1f1b36";

        List<HistoricActivityInstance> hais = historyService.createHistoricActivityInstanceQuery()
                .activityId(nodeId)
                .unfinished()
                .orderByHistoricActivityInstanceStartTime()
                .asc()
                .list();

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

        if (CollUtil.isEmpty(hais)) {
            log.info("没有查到 历史实例");
            return;
        }

        String instanceId = hais.get(0).getProcessInstanceId();
        log.info("instanceId :{}",instanceId);

        //查询当前未完成的此实例
        HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(instanceId)
                .unfinished()
                .singleResult();

        log.info("instance :{}",JSON.toJSONString(instance));
        if (Objects.isNull(instance)) {
            log.info("没有查到实例 或者 实例已经结束");
            return;
        }

        //2.查到 此流程实例的 项目
        ProjectInst pi = projectInstService.getOne(Wrappers.lambdaQuery(ProjectInst.class)
                .eq(ProjectInst::getInstCode, instanceId)
                .last(BizConst.LIMIT_1));
        log.info("pi :{}",JSON.toJSONString(pi));
    }
}
