/*
 * Author: wangjian
 * 生成ServiceImpl
 */
package com.tofly.flow.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.tofly.flow.entity.ProcessApprovalHistory;
import com.tofly.flow.entity.ProcessInstance;
import com.tofly.flow.entity.ProcessInstanceNodeInfo;
import com.tofly.flow.entity.ProcessTemplateNode;
import com.tofly.flow.mapper.ProcessInstanceNodeInfoMapper;
import com.tofly.flow.service.ProcessApprovalHistoryService;
import com.tofly.flow.service.ProcessInstanceNodeInfoService;
import com.tofly.flow.service.ProcessInstanceService;
import com.tofly.flow.service.ProcessTemplateNodeService;
import com.tofly.flow.vo.ApprovalNodeInfoVo;

import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * ${comments}
 *
 * @author zhoux
 * @date Wed Mar 10 00:00:00 CST 2021
 */
@Service("processInstanceNodeInfoService")
public class ProcessInstanceNodeInfoServiceImpl extends ServiceImpl<ProcessInstanceNodeInfoMapper, ProcessInstanceNodeInfo> implements ProcessInstanceNodeInfoService {
	
	@Autowired
	public  ProcessInstanceNodeInfoMapper processInstanceNodeInfoMapper;
		
	@Autowired
	public  ProcessTemplateNodeService processTemplateNodeService;
		
	@Autowired
	public  ProcessInstanceService processInstanceService;
	
	@Autowired
	public  ProcessApprovalHistoryService processApprovalHistoryService;	
	
	
	
	/**
	 * 流程节点审批
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Map<String, String> processApproval(ApprovalNodeInfoVo approvalNodeInfoVo)  throws Exception{
		Map<String,String> returnMap =new HashMap<String,String>();

		ProcessInstanceNodeInfo node = processInstanceNodeInfoMapper.selectOne(Wrappers.<ProcessInstanceNodeInfo>lambdaQuery()
				.eq(ProcessInstanceNodeInfo::getProcessId,approvalNodeInfoVo.getProcessId())
				.eq(ProcessInstanceNodeInfo::getNodeAlias,approvalNodeInfoVo.getNodeAlias())
				.eq(ProcessInstanceNodeInfo::getApprovalPersonId,approvalNodeInfoVo.getApprovalPersonId()));			
		
		ProcessInstance instance = processInstanceService.getById(node.getProcessId());		
			
		ProcessTemplateNode templateNode = processTemplateNodeService.getOne(Wrappers.<ProcessTemplateNode>lambdaQuery()
				.eq(ProcessTemplateNode::getProcessTemplateId,instance.getProcessTemplateId())
				.eq(ProcessTemplateNode::getProcessNodeAlias,approvalNodeInfoVo.getNodeAlias()));
		
		List<ProcessInstanceNodeInfo> nodeList = processInstanceNodeInfoMapper.selectList(Wrappers.<ProcessInstanceNodeInfo>lambdaQuery()
				.eq(ProcessInstanceNodeInfo::getProcessId,approvalNodeInfoVo.getProcessId())
				.eq(ProcessInstanceNodeInfo::getNodeAlias,approvalNodeInfoVo.getNodeAlias()));		
		
		ProcessInstanceNodeInfo processInstanceNodeInfo =new ProcessInstanceNodeInfo();
		
		BeanUtils.copyProperties(processInstanceNodeInfo,approvalNodeInfoVo);
		
		processInstanceNodeInfo.setId(node.getId());			
		processInstanceNodeInfo.setApprovalTime(new Date());
		
		processInstanceNodeInfoMapper.updateById(processInstanceNodeInfo);		
		processInstanceNodeInfo.setNodeSortNum(instance.getCurrentNodeSort());

		/**
		 * 执行流程，并更新流程节点信息
		 */
		switch(templateNode.getApprovalType()) {
			case 1:{
				//审批通过
				if(processInstanceNodeInfo.getApprovalStatus()==1) {									
					processInstanceService.executeProcessInstance(processInstanceNodeInfo,1);
				//审批不通过 回退
				}else if(processInstanceNodeInfo.getApprovalStatus()==2){
					processInstanceService.executeProcessInstance(processInstanceNodeInfo,2);
					
					ProcessInstanceNodeInfo emptyNode =new ProcessInstanceNodeInfo();
					emptyNode.setApprovalSuggest("");
					emptyNode.setApprovalStatus(0);
					emptyNode.setApprovalTime(null);
											
					processInstanceNodeInfoMapper.update(emptyNode, Wrappers.<ProcessInstanceNodeInfo>lambdaQuery()
					.eq(ProcessInstanceNodeInfo::getProcessId,processInstanceNodeInfo.getProcessId())
					.eq(ProcessInstanceNodeInfo::getNodeSortNum,processInstanceNodeInfo.getNodeSortNum()));
					
					processInstanceNodeInfoMapper.update(emptyNode, Wrappers.<ProcessInstanceNodeInfo>lambdaQuery()
						.eq(ProcessInstanceNodeInfo::getProcessId,processInstanceNodeInfo.getProcessId())
						.eq(ProcessInstanceNodeInfo::getNodeSortNum,processInstanceNodeInfo.getNodeSortNum()-1));					
				//审批不通过 拒绝
				}else{
					instance.setProcessStatus(3);
					processInstanceService.updateById(instance);
				}
				break;															
			}
			case 2:{	
				
				if(processInstanceNodeInfo.getApprovalStatus()==1) {
					List<ProcessInstanceNodeInfo> succNodeList = processInstanceNodeInfoMapper.selectList(Wrappers.<ProcessInstanceNodeInfo>lambdaQuery()
							.eq(ProcessInstanceNodeInfo::getProcessId,processInstanceNodeInfo.getProcessId())
							.eq(ProcessInstanceNodeInfo::getNodeAlias,processInstanceNodeInfo.getNodeAlias())
							.eq(ProcessInstanceNodeInfo::getApprovalStatus,1));		
					
					if(succNodeList.size()==nodeList.size()) {
						processInstanceService.executeProcessInstance(processInstanceNodeInfo,1);
					}
				}else if(processInstanceNodeInfo.getApprovalStatus()==2) {	
					List<ProcessInstanceNodeInfo> failNodeList = processInstanceNodeInfoMapper.selectList(Wrappers.<ProcessInstanceNodeInfo>lambdaQuery()
							.eq(ProcessInstanceNodeInfo::getProcessId,processInstanceNodeInfo.getProcessId())
							.eq(ProcessInstanceNodeInfo::getNodeAlias,processInstanceNodeInfo.getNodeAlias())
							.eq(ProcessInstanceNodeInfo::getApprovalStatus,2));	
					
					if(failNodeList.size()==nodeList.size()) {
						processInstanceService.executeProcessInstance(processInstanceNodeInfo,2);
					}	
					ProcessInstanceNodeInfo emptyNode =new ProcessInstanceNodeInfo();
					emptyNode.setApprovalSuggest("");
					emptyNode.setApprovalStatus(0);
					emptyNode.setApprovalTime(null);
											
					processInstanceNodeInfoMapper.update(emptyNode, Wrappers.<ProcessInstanceNodeInfo>lambdaQuery()
					.eq(ProcessInstanceNodeInfo::getProcessId,processInstanceNodeInfo.getProcessId())
					.eq(ProcessInstanceNodeInfo::getNodeAlias,processInstanceNodeInfo.getNodeAlias())
					.eq(ProcessInstanceNodeInfo::getApprovalPersonId,approvalNodeInfoVo.getApprovalPersonId()));
				}else {
					List<ProcessInstanceNodeInfo> refuseNodeList = processInstanceNodeInfoMapper.selectList(Wrappers.<ProcessInstanceNodeInfo>lambdaQuery()
							.eq(ProcessInstanceNodeInfo::getProcessId,processInstanceNodeInfo.getProcessId())
							.eq(ProcessInstanceNodeInfo::getNodeAlias,processInstanceNodeInfo.getNodeAlias())
							.eq(ProcessInstanceNodeInfo::getApprovalStatus,3));	
					if(refuseNodeList.size()==nodeList.size()) {
						instance.setProcessStatus(3);
						processInstanceService.updateById(instance);
					}
				}				
				break;
			}
			case 3:{	
				if(processInstanceNodeInfo.getApprovalStatus()==1) {
					processInstanceService.executeProcessInstance(processInstanceNodeInfo,1);
				}else if(processInstanceNodeInfo.getApprovalStatus()==2) {
					processInstanceService.executeProcessInstance(processInstanceNodeInfo,2);
					ProcessInstanceNodeInfo emptyNode =new ProcessInstanceNodeInfo();
					emptyNode.setApprovalSuggest("");
					emptyNode.setApprovalStatus(0);
					emptyNode.setApprovalTime(null);
											
					processInstanceNodeInfoMapper.update(emptyNode, Wrappers.<ProcessInstanceNodeInfo>lambdaQuery()
					.eq(ProcessInstanceNodeInfo::getProcessId,processInstanceNodeInfo.getProcessId())
					.eq(ProcessInstanceNodeInfo::getNodeSortNum,processInstanceNodeInfo.getNodeSortNum()));
					
					processInstanceNodeInfoMapper.update(emptyNode, Wrappers.<ProcessInstanceNodeInfo>lambdaQuery()
						.eq(ProcessInstanceNodeInfo::getProcessId,processInstanceNodeInfo.getProcessId())
						.eq(ProcessInstanceNodeInfo::getNodeSortNum,processInstanceNodeInfo.getNodeSortNum()-1));	
				}else {
					instance.setProcessStatus(3);
					processInstanceService.updateById(instance);
				}
				
				break;													
			}
			default:{
				break;
			}
		}
		
		//添加审批历史记录
		List<ProcessApprovalHistory> historyList =  processApprovalHistoryService.list(Wrappers.<ProcessApprovalHistory>lambdaQuery()
				.eq(ProcessApprovalHistory::getProcessId,processInstanceNodeInfo.getProcessId()));
		
		ProcessApprovalHistory history =new ProcessApprovalHistory();					
		BeanUtils.copyProperties(history,processInstanceNodeInfo);
		
		history.setId(null);
		history.setOperateNum(historyList.size()+1);					
		processApprovalHistoryService.save(history);
		
		
		returnMap.put("flag", "true");
		returnMap.put("msg", "审批成功");
		
		return returnMap;
	}
}