package com.blueland.bpm.engine.core.executor;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.activiti.engine.repository.ProcessDefinition;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.blueland.bpm.engine.core.model.ActivityDefinitionModel;
import com.blueland.bpm.engine.core.model.ActivityResourceModel;
import com.blueland.bpm.engine.core.model.ExceptionErrorCode;
import com.blueland.bpm.engine.core.model.ProcessInputModel;
import com.blueland.bpm.engine.core.model.ProcessInstanceModellBuilder;
import com.blueland.bpm.engine.core.service.AbstractServiceHelper;
import com.blueland.bpm.engine.core.service.ProcessConfigService;
import com.blueland.bpm.engine.core.service.ProcessDefinitionService;
import com.blueland.bpm.engine.core.service.ProcessInstanceService;
import com.blueland.bpm.engine.util.WorkFlowContants;
import com.blueland.bpm.engine.util.WorkFlowException;
import com.blueland.bpm.identity.OrgService;
import com.blueland.bpm.identity.UserService;
import com.blueland.bpm.identity.model.Org;
import com.blueland.bpm.identity.model.User;

/**
 * 流程执行基类类
 * 
 * @version: 1.0
 * @author lw
 */
@Service
public abstract class AbstractProcessExecutor extends AbstractServiceHelper {
	@Resource(name = "processConfigServiceImpl")
	ProcessConfigService processConfigService;
	@Resource(name = "processDefinitionServiceImpl")
	ProcessDefinitionService processDefinitionService;
	@Resource(name = "processInstanceServiceImpl")
	ProcessInstanceService processInstanceService;
	@Autowired
	UserService userService;
	@Autowired
	OrgService orgService;
	@Resource(name = "processInstanceModellBuilder")
	ProcessInstanceModellBuilder processInstanceModellBuilder;

	protected void validateProcessInputModel(ProcessInputModel processInputModel)
			throws WorkFlowException {
		if (processInputModel == null) {
			throw new WorkFlowException(ExceptionErrorCode.B2001,"流程输入参数对象{processInputModel}不能为空");
		}
		if (StringUtils.isEmpty(processInputModel.getWf_sendUserId())) {
			throw new WorkFlowException(ExceptionErrorCode.B2001,String.format(
					"流程输入参数{发送人:wf_sendUserId}不能为空,processInputModel[%s]",
					processInputModel));
		} /*else if (StringUtils.isEmpty(processInputModel.getWf_sendUserOrgId())) {
			throw new WorkFlowException(ExceptionErrorCode.B2001,String.format(
					"流程输入参数{发送人组织ID:wf_sendUserOrgId}不能为空,processInputModel[%s]",
					processInputModel));
		}*/ else if (StringUtils.isEmpty(processInputModel.getWf_procTitle())) {
			throw new WorkFlowException(ExceptionErrorCode.B2001,String.format(
					"流程输入参数{流程标题:wf_procTitle}不能为空,processInputModel[%s]",
					processInputModel));
		} else if (StringUtils.isEmpty(processInputModel.getWf_procDefId())) {
			throw new WorkFlowException(ExceptionErrorCode.B2001,String.format(
					"流程输入参数{流程定义ID:wf_procDefId}不能为空,processInputModel[%s]",
					processInputModel));
		}
	}

	protected void additionalProcessInputModel(
			ProcessInputModel processInputModel,
			ProcessDefinition processDefinition) throws WorkFlowException {
			if (StringUtils.isEmpty(processInputModel.getWf_procDefName())) {
				processInputModel
						.setWf_procDefName(processDefinition.getName());
			}
			/*
			 * User user =null; if
			 * (StringUtils.isEmpty(processInputModel.getWf_sendUserOrgId()))
			 * {//喏维赞允许部分流程（与组织无关流程）组织ID可为空，用用户最新组织走流程 user =
			 * userService.getUserById(processInputModel.getWf_sendUserId());
			 * processInputModel.setWf_sendUserOrgId(user.getOrgId());
			 * processInputModel.setWf_sendUserOrgName(user.getOrgName()); }else{ user =
			 * userService.getUserByCode(processInputModel.getWf_sendUserId(),
			 * processInputModel.getWf_sendUserOrgId()); }
			 */
			/*
			 * if (user == null) { throw new WorkFlowException( ExceptionErrorCode.B2058,
			 * String.format( "通过发送人和发送人组织无法获取到用户对象,流程执行失败,processInputModel[%s]",
			 * processInputModel)); }
			 */
			if (StringUtils.isNotEmpty(processInputModel.getWf_sendUserId())) {
				processInputModel.setWf_sender(processInputModel.getWf_sendUserId());
			}
			/*
			 * processInputModel.setWf_sender(user.getUserId());
			 * processInputModel.setWf_sendUserName(user.getUserName()); if
			 * (StringUtils.isEmpty(processInputModel.getWf_sendUserOrgName())) { Org org =
			 * orgService.getOrgById(processInputModel .getWf_sendUserOrgId());
			 * processInputModel.setWf_sendUserOrgName(org != null ? org .getOrgName() :
			 * ""); }
			 */
			if (processInputModel.getWf_businessDataObject() != null) {
				processInputModel.getWf_variables().put(WorkFlowContants.WF_BUSINESS_DATA_OBJECT_KEY,
						processInputModel.getWf_businessDataObject());
			}
			if (processInputModel.getWf_throughBizDataObject() != null) {
				processInputModel.getWf_variables().put(WorkFlowContants.WF_THROUGH_BUSINESS_DATA_OBJECT_KEY,
						processInputModel.getWf_throughBizDataObject());
			}
		
	}

	protected void autoSetNextActDefId(ProcessInputModel processInputModel)
			throws WorkFlowException {
		// 必须没有选择下一步环节
		if (StringUtils.isNotBlank(processInputModel.getWf_nextActDefId())) {
			return;
		}
		// 自动查询下一环节
		List<ActivityDefinitionModel> activityDefinitionModels = processDefinitionService
				.getNextActivity(processInputModel.getWf_procInstId(),
						processInputModel.getWf_procDefId(),
						processInputModel.getWf_curActDefId(),
						processInputModel.getFields());
		if (activityDefinitionModels == null
				|| activityDefinitionModels.isEmpty()) {
			throw new WorkFlowException(ExceptionErrorCode.B2005,String.format(
					"无法找到当前环节输出环节,流程流转失败,processInputModel[%s]",
					processInputModel));
		}
		ActivityDefinitionModel activityDefinitionModel = activityDefinitionModels
				.get(0);
		processInputModel.setWf_nextActDefId(activityDefinitionModel
				.getActDefId());
		processInputModel.setWf_nextActDefType(activityDefinitionModel
				.getActType());
		processInputModel.setWf_nextActDefName(activityDefinitionModel
				.getActDefName());
	}

	protected List<String> convertReceivers(String receiver) {
		String[] receiverArray = null;
		if (receiver.indexOf(",") != -1) {
			receiverArray = receiver.split(",");
		} else {
			receiverArray = new String[] { receiver };
		}
		List<String> receiverList = new ArrayList<String>(receiverArray.length);
		CollectionUtils.addAll(receiverList, receiverArray);
		return receiverList;
	}

	protected String getTreeNodeOneUser(List<ActivityResourceModel> users) {
		for (ActivityResourceModel treeNode : users) {
			if ("USER".equals(treeNode.getType())) {
				return treeNode.getRealId();
			}
		}
		return "";
	}
}
