package me.zhengjie.modules.dm.activiti;

import me.zhengjie.modules.dm.activiti.event.ActivitiEvent;
import me.zhengjie.modules.dm.activiti.status.OperationStatus;
import me.zhengjie.modules.dm.information.domain.DmInformation;
import me.zhengjie.modules.dm.information.repository.DmInformationRepository;
import me.zhengjie.modules.dm.user.service.DmUserService;
import me.zhengjie.modules.dm.user.util.DmUserUtils;
import me.zhengjie.utils.StringUtils;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 监听自定义事件(触发工作流的操作)
 */
@Component
public class ActivitiPrinterListener implements ApplicationListener<ActivitiEvent> {

    private final String RESERVE_APPROVE_FLOW = "infomationApproval";

    @Autowired
    private ProcessEngine engine;

    @Autowired
    private DmInformationRepository informationRepository;

    @Override
    public void onApplicationEvent(ActivitiEvent event) {
        System.out.println("onApplicationEvent == > "+event.getStatus());
        DmInformation info = (DmInformation) event.getInfo();
        Map<String,Object> variables = new HashMap<>();
        //提交申请
        if(event.getStatus().equals(OperationStatus.SUBMIT) ){
            //申请操作信息
//            variables.put("createUser",info.getRequestUser().getId());
//            variables.put("user_id",info.getRequestUser().getId());
            variables.put("user_table","dm_user");
            variables.put("op_id",info.getId());
            variables.put("op_table","dm_information");
            variables.put("is_auto",1);//是否自动执行下一节点(0-自动 1-不自动)
            //启动流程
            runFlow(RESERVE_APPROVE_FLOW,variables);
        }
        //提交审批人
        if(event.getStatus().equals(OperationStatus.SUBMIT_APPROVAL_USER)){
            List<Long> approveList = new ArrayList<>();
            //下一节点,审批人信息
            Map<String,Object> approveInfo =  informationRepository.selectInfoApproveUserNames(info.getId());
            if(approveInfo != null){
                String userIds = (String) approveInfo.get("userIds");
                if(StringUtils.isNotBlank(userIds)){
                    String[] arr = userIds.split(",");
                    for(String s:arr){
                        if(StringUtils.isNotBlank(s)){
                            approveList.add(Long.parseLong(s));
                        }
                    }
                }
            }
            variables.put("approvalUserList",approveList);
            completeTask(info.getTaskId(),variables);
        }
        //审批
        if(event.getStatus().equals(OperationStatus.APPROVE)){
            variables.put("approve_user_id",DmUserUtils.getCurrDmUser().getId());
            variables.put("approve_user_table","dm_user");
            variables.put("op_id",info.getId());
            variables.put("op_table","dm_information");
            variables.put("status",info.getStatus());
            variables.put("reason",info.getApprovalRemark());
            variables.put("is_auto",1);//不需要自动执行下一节点
            completeTask(info.getTaskId(),variables);
        }
        //终止流程实例
        if(event.getStatus().equals(OperationStatus.PUZ_INST)){
            puzInstance(info.getProcInstId(),event.getRemark());
        }
    }

    /**
     * 启动工作流
     */
    private ProcessInstance runFlow(String key, Map<String,Object> variables){
        //根据Key值取最新的流程定义
        RepositoryService repositoryService = engine.getRepositoryService();
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
        processDefinitionQuery.processDefinitionKey(key);
        processDefinitionQuery.orderByProcessDefinitionVersion().desc();
        List<ProcessDefinition> list = processDefinitionQuery.list();
        //启动
        RuntimeService runtimeService = engine.getRuntimeService();
        return runtimeService.startProcessInstanceById(list.get(0).getId(),variables);
    }

    /**
     * 完成任务
     * @param taskId 任务id
     * @param variables 参数
     */
    private void completeTask(String taskId, Map<String,Object> variables){
        TaskService taskService = engine.getTaskService();
        taskService.complete(taskId,variables);
    }

    /**
     * 终止流程实例(删除会议时,删除还在进行中的关联流程实例)
     * @param procInstId 实例id
     * @param remark 原因
     */
    public void puzInstance(String procInstId,String remark){
        engine.getRuntimeService().deleteProcessInstance(procInstId,remark);
    }

}
