package org.security.flow.business.listener.task;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.api.delegate.Expression;
import org.flowable.engine.delegate.TaskListener;
import org.flowable.task.service.delegate.DelegateTask;
import org.security.flow.core.constant.ProcessConstant;
import org.security.flow.core.enums.CandidateTypeEnum;
import org.security.flow.core.utils.TaskUtil;
import org.security.system.user.feign.IUserClient;
import org.security.system.user.vo.UserVO;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.SpringUtil;
import org.springblade.core.tool.utils.StringPool;
import org.springframework.stereotype.Component;
import org.flowable.engine.TaskService;

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

/**
 * @Author: qxqx
 * @Create: 2022/9/15
 * @Description:
 */
@Slf4j
@Data
@Component
public class SetCandidateTaskListener implements TaskListener {

	private Expression candidateType;

	@Override
	public void notify(DelegateTask delegateTask) {
		log.info(">>>>>>>>>> 设置流程处理人：开始");
		String typeStr = (String) candidateType.getValue(delegateTask);
		log.info(">>>>>>>>>> 处理人角色为：" + typeStr);
		String[] types = typeStr.split(StringPool.COMMA);
		for (int i = 0; i < types.length; i++) {
			if (!CandidateTypeEnum.getValues().contains(types[i])) {
				log.error(">>>>>>>>>> 不支持的节点审批人配置：" + types[i] + "");
				throw new ServiceException("不支持的节点审批人配置：" + types[i] + "");
			}
		}
		List<UserVO> candidateUsers = new ArrayList<>();
		IUserClient userClient = SpringUtil.getBean(IUserClient.class);
		Long userId = (Long) delegateTask.getVariable(ProcessConstant.START_PROC_USER_ID);
		if (Func.isNull(userId) || Func.isEmpty(userId)) {
			log.info(">>>>>>>>>> 流程未设置变量 流程开启用户id，尝试使用登录用户开启流程");
			userId = AuthUtil.getUserId();
			log.info(">>>>>>>>>> 当前登录用户id：" + userId);
		}
		if (-1 == userId) {
			log.error(">>>>>>>>>> 获取流程开启用户失败！");
			throw new ServiceException("获取流程开启用户失败！");
		}
		for (int i = 0; i < types.length; i++) {
			if (CandidateTypeEnum.fromValue(types[i]) == CandidateTypeEnum.HEAD_LEADER) {
				candidateUsers.addAll(getUsers(userClient.headLeaders(userId), CandidateTypeEnum.HEAD_LEADER.getName()));
			}
			if (CandidateTypeEnum.fromValue(types[i]) == CandidateTypeEnum.HEAD_SEC_LEADER) {
				candidateUsers.addAll(getUsers(userClient.headSecLeaders(userId), CandidateTypeEnum.HEAD_SEC_LEADER.getName()));
			}
			if (CandidateTypeEnum.fromValue(types[i]) == CandidateTypeEnum.HEAD_SAFER) {
				candidateUsers.addAll(getUsers(userClient.headSafers(userId), CandidateTypeEnum.HEAD_SAFER.getName()));
			}
			if (CandidateTypeEnum.fromValue(types[i]) == CandidateTypeEnum.BRANCH_LEADER) {
				candidateUsers.addAll(getUsers(userClient.branchLeaders(userId), CandidateTypeEnum.BRANCH_LEADER.getName()));
			}
			if (CandidateTypeEnum.fromValue(types[i]) == CandidateTypeEnum.BRANCH_SAFER) {
				candidateUsers.addAll(getUsers(userClient.branchSafers(userId), CandidateTypeEnum.BRANCH_SAFER.getName()));
			}
			if (CandidateTypeEnum.fromValue(types[i]) == CandidateTypeEnum.SUB_LEADER) {
				candidateUsers.addAll(getUsers(userClient.subLeaders(userId), CandidateTypeEnum.SUB_LEADER.getName()));
			}
			if (CandidateTypeEnum.fromValue(types[i]) == CandidateTypeEnum.SUB_SAFER) {
				candidateUsers.addAll(getUsers(userClient.subSafers(userId), CandidateTypeEnum.SUB_SAFER.getName()));
			}
			if (CandidateTypeEnum.fromValue(types[i]) == CandidateTypeEnum.DEPT_LEADER) {
				candidateUsers.addAll(getUsers(userClient.deptLeaders(userId), CandidateTypeEnum.DEPT_LEADER.getName()));
			}
		}
		if (candidateUsers.isEmpty()) {
			log.error(">>>>>>>>>> 未找到指定审批用户！");
			throw new ServiceException("未找到指定审批用户！");
		}
		List<String> leaderList = candidateUsers.stream().map(leader -> TaskUtil.getTaskUser(Long.toString(leader.getId()))).collect(Collectors.toList());
		if (leaderList.size() == 1) {
			log.info(">>>>>>>>>> 找到一个处理人，设置一人待办");
			log.info(">>>>>>>>>> 处理人id：" + userId);
			TaskService taskService = SpringUtil.getBean(TaskService.class);
			if (null != taskService) {
				taskService.claim(delegateTask.getId(), leaderList.get(0));
			} else {
				log.error(">>>>>>>>>> 获取TaskService失败！");
				throw new ServiceException("获取TaskService失败！");
			}
		} else {
			log.info(">>>>>>>>>> 找到多个处理人，设置多人待签");
			log.info(">>>>>>>>>> 处理人id：" + leaderList.toString());
			delegateTask.addCandidateUsers(leaderList);
		}
		log.info(">>>>>>>>>> 设置流程处理人：结束");
	}

	private List<UserVO> getUsers(R<List<UserVO>> res, String userTypeMsg) {
		if (!res.isSuccess()) {
			throw new ServiceException("查找用户类型“" + userTypeMsg + "”失败！");
		}
		return res.getData();
	}
}
