package cn.palmte.work.service;


import cn.palmte.work.config.activiti.ActTaskIndexEnum;
import cn.palmte.work.model.ActTaskDef;
import cn.palmte.work.model.Admin;
import cn.palmte.work.model.AdminRepository;
import cn.palmte.work.model.enums.ProcessStatus;
import cn.palmte.work.utils.ActUtil;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.runtime.ProcessInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;


/**
 * 流程节点监听
 */
@Service
public class ActListenerService {
    private static final Logger logger = LoggerFactory.getLogger(ActListenerService.class);


    @Autowired
    private ActTaskDefService actTaskDefService;

    @Autowired
    private ProjectInstanceService projectInstanceService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private ActUtil actUtil;

    @Autowired
    private AdminRepository adminRepository;

    @Autowired
    ProjectProcessService projectProcessService;

    /**
     * 任务节点创建后监听 动态设置审批人
     *
     * @param delegateTask
     * @throws Exception
     */
    public void create(DelegateTask delegateTask) {
        String procInsId = delegateTask.getProcessInstanceId();
        logger.info("--节点创建后监听--  procInsId:{},  {}", procInsId, delegateTask);
        logger.info("**** rwcjjt【{}】任务创建监听 procInsId:{} **** ", delegateTask, procInsId);

        String procDefId = delegateTask.getProcessDefinitionId();
        String taskDefKey = delegateTask.getTaskDefinitionKey();
        List<String> candidateUsers = actTaskDefService.findCandidateUsers(procDefId, procInsId, taskDefKey);
        logger.info("**** rwcjjt 任务创建监听 查询候选人 procInsId:{}，任务名称：{}，候选人：{} **** ", procInsId, delegateTask.getName(), candidateUsers);

        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(procInsId).singleResult();
        if (processInstance != null) {
            try {
                updateProjectApprover(candidateUsers, processInstance, procDefId, taskDefKey);
            } catch (Exception e) {
                logger.error("updateProjectApproverError", e);
            }
        }

        delegateTask.addCandidateUsers(candidateUsers);
    }


    /**
     * 流程结束监听 更新项目状态为审批通过
     *
     * @param delegateExecution
     */
    public void end(DelegateExecution delegateExecution) {
        String procInsId = delegateExecution.getProcessInstanceId();
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(procInsId).singleResult();
        int projectId = Integer.parseInt(processInstance.getBusinessKey());

        String procDefId = processInstance.getProcessDefinitionId();
        if (actUtil.isNewProcess(procDefId)) {
            logger.info("**** lcjsjt 流程结束监听 更新项目状态为审批通过 ****  procInsId:{}, procDefId:{}, projectId:{}", procInsId, procDefId, projectId);
            projectProcessService.updateProcessStatus(projectId, ProcessStatus.audit_passed);
        }
    }


    /**
     * 更新项目审批人
     *
     * @param candidateUsers
     * @param processInstance
     */
    private void updateProjectApprover(List<String> candidateUsers, ProcessInstance processInstance,
                                       String procDefId, String taskDefKey) {
        String businessKey = processInstance.getBusinessKey();
        ActTaskDef actTaskDef = actTaskDefService.findFirstByProcDefIdAndTaskKey(procDefId, taskDefKey);
        //找到当前有效的用户
        List<Integer> enableUsers = currentEnableUsers(candidateUsers);
        boolean notFirstUserTask = actTaskDef != null && actTaskDef.getTaskIndex() != ActTaskIndexEnum.FIRST_USER_TASK.getIndex();
        logger.info("**** rwcjjt 更新审批人 procInsId:{}, projectId:{}, enableUsers:{}, notFirstUserTask:{} **** ",
                processInstance.getProcessInstanceId(), businessKey, enableUsers, notFirstUserTask);

        if (actUtil.isFourcalProcess(procDefId)) {
            int adminId = 0;//默认审批人设置为空
            if (notFirstUserTask && !enableUsers.isEmpty()) {
                adminId = enableUsers.get(0);//四算项目只支持一个审批人
            }
            logger.info("**** rwcjjt 任务创建监听 更新审批人1 procInsId:{}, projectId:{}, adminId:{} **** ",
                    processInstance.getProcessInstanceId(), businessKey, adminId);
            projectInstanceService.updateApprover(Integer.parseInt(businessKey), adminId);
        } else if (actUtil.isNewProcess(procDefId)) {
            if (!enableUsers.isEmpty()) {
                projectProcessService.updateAudit(Integer.parseInt(businessKey), null, enableUsers);
            }
            logger.info("**** rwcjjt 任务创建监听 更新审批人2 procInsId:{}, projectId:{}, enableUsers:{} **** ",
                    processInstance.getProcessInstanceId(), businessKey, enableUsers);
        }
    }

    private List<Integer> currentEnableUsers(List<String> candidateUsers) {
        return candidateUsers.stream().map(ele -> adminRepository.findOne(Integer.parseInt(ele)))
                .filter(ele -> !ele.isDeleted() && ele.getEnabled() == 1)
                .map(Admin::getId)
                .collect(Collectors.toList());
    }
}
