package com.xjrsoft.module.job;

import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import com.xjrsoft.common.constant.GlobalConstant;
import com.xjrsoft.common.utils.DatasourceUtil;
import com.xjrsoft.common.utils.DateUtils;
import com.xjrsoft.module.evaluate.entity.EvaluateManage;
import com.xjrsoft.module.oa.utils.SendMessageUtil;
import com.xjrsoft.module.workflow.entity.WorkflowExtra;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * 流程未处理提醒
 */
@Component
@Slf4j
public class ProcessNotProcessingAlertTask {
    /**
     * 流程未处理提醒
     */
    @Scheduled(cron = "0 0 14 * * ?")
    public void alertProcessNotProcessing() {
        System.out.printf("定时提醒流程未处理：%s", DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN));
        DataSource datasource = DatasourceUtil.getDataSource(GlobalConstant.DEFAULT_DATASOURCE_KEY);
        try {
            Db use = Db.use(datasource);

            //获取未结束流程的流程id
            String listUncloseProcessIdSql = "SELECT DISTINCT process_id " +
                    "FROM xjr_workflow_record w1 " +
                    "WHERE NOT EXISTS ( " +
                    "        SELECT 1 " +
                    "        FROM xjr_workflow_record w2 " +
                    "        WHERE w2.node_id = 'Event_140v10k' " +
                    "          AND w1.process_id = w2.process_id " +
                    "    );";
            List<Entity> listUncloseProcessId = use.query(listUncloseProcessIdSql);

            if(!listUncloseProcessId.isEmpty()){
                //获取所有未完成流程的所有节点
                String uncloseProcessIdStr = listUncloseProcessId.stream()
                        .map(entity -> "'" + entity.getStr("process_id") + "'")
                        .collect(Collectors.joining(","));
                String listWorkflowExtraSql = "select * " +
                        "from xjr_workflow_extra "
                        + "where process_id in (" + uncloseProcessIdStr + ");";;
                List<WorkflowExtra> workflowExtraList = use.query(listWorkflowExtraSql, WorkflowExtra.class);

                List<String> uncloseProcessIdList = listUncloseProcessId.stream()
                        .map(entity -> entity.getStr("process_id"))
                        .collect(Collectors.toList());

                //筛选出每个流程的最后一个节点的记录，需要的是有任务节点id的记录
                List<WorkflowExtra> workflowExtraLastNodeList = new ArrayList<>();
                LocalDateTime now = LocalDateTime.now();
                for(String processId : uncloseProcessIdList){
                    workflowExtraList.stream()
                            .filter(e -> e.getProcessId().equals(processId))
                            .max(Comparator.comparing(WorkflowExtra::getStartTime))
                            .ifPresent(e -> {
                                if((e.getEndTime() == null || e.getEndTime().toString().equals("")) && e.getApproveUserIds() != null && !e.getApproveUserIds().equals("")){
                                    // 计算两个时间之间的差值
                                    Duration duration = Duration.between(e.getStartTime(), now);
                                    if (duration.toHours() > 24) {
                                        //System.out.println("时间差大于24小时");
                                        workflowExtraLastNodeList.add(e);
                                    }
                                }
                            });
                }

                //对未结束的流程节点进行处理，通知下一个节点需要处理的人
                Map<String, StringBuilder> message = new HashMap<>();
                for (WorkflowExtra w : workflowExtraLastNodeList){
                    String approveUserIds = w.getApproveUserIds();
                    String[] aapproveUserIdArray = approveUserIds.trim().split(",");
                    for (String str : aapproveUserIdArray){
                        if(message.containsKey(str)){
                            message.get(str).append(",").append(w.getProcessName());
                        }else {
                            message.put(str, new StringBuilder(w.getProcessName()));
                        }
                    }
                }

//                SendMessageUtil.sendWorkflowUnapprovedWx(message);

                CompletableFuture.runAsync(() -> {
                    SendMessageUtil.sendWorkflowUnapprovedWx(message);
                });

//                System.err.println(workflowExtraLastNodeList.size());
//                System.err.println(workflowExtraLastNodeList.get(0));
            }
        } catch (Exception e) {
            log.error(e.getMessage(), "定时提醒流程未处理");
        }
    }
}
