package com.artfess.bpm.engine.inst;

import com.artfess.base.query.Direction;
import com.artfess.base.query.QueryFilter;
import com.artfess.base.query.QueryOP;
import com.artfess.base.util.AppUtil;
import com.artfess.base.util.BeanUtils;
import com.artfess.base.util.StringUtil;
import com.artfess.bpm.api.model.process.task.BpmTaskOpinion;
import com.artfess.bpm.api.service.BpmOpinionService;
import com.artfess.bpm.persistence.manager.BpmCheckOpinionManager;
import com.artfess.bpm.persistence.model.DefaultBpmCheckOpinion;
import com.artfess.bpm.util.BpmCheckOpinionUtil;
import com.artfess.uc.api.impl.service.UserServiceImpl;
import com.artfess.uc.api.model.IUser;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class DefaultBpmOpinionService implements BpmOpinionService {

	@Resource
	BpmCheckOpinionManager bpmCheckOpinionManager;

	@Override
	public List<BpmTaskOpinion> getTaskOpinions(String procInstId) {
		List<DefaultBpmCheckOpinion> defaultBpmCheckOpinions = bpmCheckOpinionManager.getByInstId(procInstId);
		return defaultBpmCheckOpinions.stream().collect(Collectors.toList());
	}

	@Override
	public List<BpmTaskOpinion> getByInstNodeId(String instId, String nodeId) {
		return bpmCheckOpinionManager.getByInstNodeId(instId, nodeId).stream().collect(Collectors.toList());
	}


	@Override
	public Map<String, Set<String>> getHisAuditorByInstId(String instId,boolean transToAccount) {
		String topInstId = bpmCheckOpinionManager.getTopInstId(instId);
		QueryFilter<DefaultBpmCheckOpinion> queryFilter = QueryFilter.build();
		queryFilter.addFilter("proc_inst_id_", StringUtil.join(bpmCheckOpinionManager.getListByInstId(topInstId)), QueryOP.IN);
		queryFilter.setDefaultSort("complete_time_", Direction.DESC);
		List<DefaultBpmCheckOpinion> opinionList = bpmCheckOpinionManager.queryNoPage(queryFilter);
		Map<String, Set<String>> map = new HashMap<>();
		if (BeanUtils.isEmpty(opinionList)) {
			return map;
		}
		//上一个在整理的节点id
		String preSortOutNodeId ="";
		//已经整理过的节点集合。在集合里的不会再放入
		Set<String> alreadySortOutNodeId = new HashSet<>();
		Set<String> allAuditorIds =  new HashSet<>();
		for (DefaultBpmCheckOpinion opinion : opinionList) {
			String nodeId = opinion.getTaskKey();
			//不是主要的审批动作||没有节点id||该节点之前已经整理过的。都直接跳过
			if (!BpmCheckOpinionUtil.effectNodeTransActions.contains(opinion.getStatus()) || StringUtil.isEmpty(nodeId) || alreadySortOutNodeId.contains(nodeId)) {
				continue;
			}
			Set<String> userIds = map.get(nodeId);
			if (BeanUtils.isEmpty(userIds)) {
				userIds = new HashSet<>();
			}
			userIds.add(opinion.getAuditor());
			allAuditorIds.add(opinion.getAuditor());
			map.put(nodeId, userIds);
			//如果当前节点id和上一个正在整理的节点不一样，则表明上一个节点的审批人已经整理完毕。则放入
			if (StringUtil.isNotEmpty(preSortOutNodeId) && !preSortOutNodeId.equals(nodeId)) {
				alreadySortOutNodeId.add(preSortOutNodeId);
			}
			preSortOutNodeId = nodeId;
		}
		if (BeanUtils.isNotEmpty(allAuditorIds) && transToAccount) {
			UserServiceImpl userServiceImpl = AppUtil.getBean(UserServiceImpl.class);
			List<IUser> userByIds = userServiceImpl.getUserByIds(StringUtil.join(allAuditorIds));
			if (BeanUtils.isNotEmpty(userByIds)) {
				Map<String, String> userIdAccountMap = new HashMap<>();
				for (IUser iUser : userByIds) {
					userIdAccountMap.put(iUser.getUserId(), iUser.getAccount());
				}
				for (Iterator<Entry<String, Set<String>>> iterator = map.entrySet().iterator(); iterator.hasNext();) {
					Entry<String, Set<String>> next = iterator.next();
					Set<String> ids = next.getValue();
					Set<String> accounts = new HashSet<>();
					for (String id : ids) {
						accounts.add(userIdAccountMap.get(id));
					}
					next.setValue(accounts);
				}
			}
		}
		return map;
	}

}
