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

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

import cn.hutool.core.util.StrUtil;
import com.blueland.bpm.common.util.SysConfig;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.delegate.JavaDelegate;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.blueland.bpm.common.util.ApplicationContextHolder;
import com.blueland.bpm.engine.config.model.DataObjectRelation;
import com.blueland.bpm.engine.config.service.DataObjectRelationManager;
import com.blueland.bpm.engine.core.model.ActivityReceiverModel;
import com.blueland.bpm.engine.core.model.ActivityResourceModel;
import com.blueland.bpm.engine.core.model.BusinessDataObject;
import com.blueland.bpm.engine.core.model.ExceptionErrorCode;
import com.blueland.bpm.engine.core.model.ProcessInputModel;
import com.blueland.bpm.engine.core.service.ProcessDefinitionService;
import com.blueland.bpm.engine.core.service.ProcessExecuteService;
import com.blueland.bpm.engine.core.service.ProcessExecuteServiceFacde;
import com.blueland.bpm.engine.util.ProcessDefinitionUtils;
import com.blueland.bpm.engine.util.WorkFlowContants;
import com.blueland.bpm.engine.util.WorkFlowException;
import com.blueland.bpm.identity.UserService;
/**
 * 流程贯穿-服务任务引擎代理
 * 
 * @version: 1.0
 * @author lw
 */
public class ThroughBizAppProcess implements JavaDelegate {
	private Logger logger = LoggerFactory.getLogger(getClass());
	private Expression procDefIdText;
	public void execute(DelegateExecution execution) throws Exception {
		ProcessExecuteServiceFacde processExecuteService = (ProcessExecuteServiceFacde) ApplicationContextHolder
				.getBean("processExecuteServiceFacde");
		ProcessInputModel oldProcessInputModel = (ProcessInputModel) execution
				.getVariables().get(WorkFlowContants.WF_PROCESS_INPUT_VARIABLE_KEY);
		if(oldProcessInputModel.getWf_receivers()==null){
			List<ActivityReceiverModel> activityReceiverModels=getGroupFirstReceiver(oldProcessInputModel.getWf_procInstId(),oldProcessInputModel.getWf_procDefId(),oldProcessInputModel.getWf_curActInstId(),oldProcessInputModel.getWf_curActDefId(),oldProcessInputModel.getWf_nextActDefId(),oldProcessInputModel.getWf_sendUserId(),oldProcessInputModel.getFields());
			oldProcessInputModel.setWf_receivers(activityReceiverModels);
		}
		List<ActivityReceiverModel> receivers= oldProcessInputModel.getWf_receivers();
		for (ActivityReceiverModel receiver : receivers) {
			ProcessInputModel newProcessInputModel = buildNewProcessInputModel(
					oldProcessInputModel, execution);
			newProcessInputModel.setWf_sendUserId(receiver.getReceiveUserId());
			newProcessInputModel.setWf_sendUserOrgId(receiver.getReceiveUserOrgId());
			List<ActivityReceiverModel> tempReceivers=new ArrayList<ActivityReceiverModel>(1);
			tempReceivers.add(receiver);
			newProcessInputModel.setWf_receivers(tempReceivers);
			ProcessDefinitionUtils.convertWf_receivers(newProcessInputModel);
			//获取流程贯穿的业务数据对象
			BusinessDataObject businessDataObject = oldProcessInputModel
					.getWf_throughBizDataObject();
			if (businessDataObject == null
					|| businessDataObject.getBizData() == null) {
				businessDataObject = oldProcessInputModel.getWf_businessDataObject();
			}
			//将流程贯穿的业务数据对象赋予wf_businessDataObject
			newProcessInputModel.getWf_variables().put("wf_businessDataObject",businessDataObject);
			newProcessInputModel.setWf_businessDataObject(businessDataObject);

			// 下面代码只是为了测试使用,上线后会删除掉
			try {
				Map newProcessVar = newProcessInputModel.getWf_variables();
				Map fields = oldProcessInputModel.getFields();
				DataObjectRelationManager dataObjectRelationManager = (DataObjectRelationManager) ApplicationContextHolder
						.getBean("dataObjectRelationManager");
				List<DataObjectRelation> dataObjectRelations = dataObjectRelationManager
						.findDataObjectRelationsByThroughProc(
								execution.getProcessDefinitionId(),
								execution.getCurrentActivityId());
				for (DataObjectRelation dataObjectRelation : dataObjectRelations) {
					Object sourceProcessVar = oldProcessInputModel.getFields().get(
							dataObjectRelation.getDataObject().getObjKey());
					newProcessVar.put(dataObjectRelation.getDataObject()
							.getObjValue(), sourceProcessVar);
					fields.put(dataObjectRelation.getDataObject().getObjValue(),
							sourceProcessVar);
				}
				//业务流程贯穿标记
				newProcessVar.put(WorkFlowContants.IS_THROUGH_BIZ_PROCESS_KEY, WorkFlowContants.IS_THROUGH_BIZ_PROCESS_YES);
			} catch (Exception e) {
				e.printStackTrace();
			}
			processExecuteService.nextExecute(newProcessInputModel);
		}
		
	}

	private ProcessInputModel buildNewProcessInputModel(ProcessInputModel oldProcessInputModel,DelegateExecution execution) {
		if (oldProcessInputModel == null) {
			oldProcessInputModel = new ProcessInputModel();
			oldProcessInputModel.setWf_sender("SYS");
		}
		ProcessInputModel newProcessInputModel = new ProcessInputModel();
		if(procDefIdText==null){
			String errorMsg="业务流程贯穿服务-贯穿流程ID为null,ProcessInputModel:"+oldProcessInputModel;
			this.logger.error(errorMsg);
			throw new WorkFlowException(ExceptionErrorCode.B2006,errorMsg); 
		}
		newProcessInputModel.setWf_procDefId(procDefIdText.getValue(execution)
				.toString());
		newProcessInputModel
				.setWf_actionType(WorkFlowContants.ACTION_TYPE_THROUGH_PROCESS);
		newProcessInputModel.setWf_businessKey(java.util.UUID.randomUUID()
				.toString());
		//绑定流程父子关系
		newProcessInputModel.setWf_appId(oldProcessInputModel.getWf_appId());
		newProcessInputModel.setWf_uniteworkUrl(oldProcessInputModel.getWf_uniteworkUrl());
		newProcessInputModel.setWf_parentProcInstId(execution.getProcessInstanceId());
		newProcessInputModel.setWf_procTitle(oldProcessInputModel.getWf_procTitle());
		newProcessInputModel.setWf_curActDefId(oldProcessInputModel.getWf_curActDefId());
		newProcessInputModel.setWf_curActDefName(oldProcessInputModel.getWf_curActDefName());
		newProcessInputModel.setWf_curActDefType(oldProcessInputModel.getWf_curActDefType());
		return newProcessInputModel;
	}
	/**
	 * 获取环节绑定资源的第一个资源值
	 * @param procInstId
	 * @param proceDefId
	 * @param curtTaskId
	 * @param curtActDefId
	 * @param nextActDefId
	 * @param userId
	 * @param conditionMap
	 * @return
	 */
	public List<ActivityReceiverModel> getGroupFirstReceiver(String procInstId,String proceDefId,String curtTaskId,String curtActDefId,String nextActDefId,String userId,Map conditionMap){
		List<ActivityReceiverModel> activityReceiverModels=new ArrayList<ActivityReceiverModel>();
		ProcessDefinitionService processDefinitionService=null;
		try{
			processDefinitionService=(ProcessDefinitionService) ApplicationContextHolder.getBean("processDefinitionServiceImpl");
		}catch(Exception e){
			try {
				Thread.sleep(9000);
			} catch (InterruptedException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			processDefinitionService=(ProcessDefinitionService) ApplicationContextHolder.getBean("processDefinitionServiceImpl");
		}
		UserService userService=(UserService) com.blueland.bpm.common.util.ApplicationContextHolder.getBean("userServiceImpl");
		com.blueland.bpm.identity.model.User user=userService.getUserById(userId);
		List<ActivityResourceModel> users=null;
		if(StringUtils.isEmpty(curtActDefId)){
			users=processDefinitionService.getResource(proceDefId, nextActDefId);
		}else{
			users = processDefinitionService
				.getActivityUserTree(procInstId,proceDefId,curtTaskId,curtActDefId,nextActDefId,user.getUserCode(),user.getOrgId(),null,conditionMap);
		}
		for (ActivityResourceModel treeNode : users) {
			if("USER".equals(treeNode.getType())){
				ActivityReceiverModel activityReceiverModel=new ActivityReceiverModel();
				activityReceiverModel.setReceiveUserId(treeNode.getId());
				activityReceiverModel.setReceiveUserOrgId(treeNode.getParentId());
				activityReceiverModels.add(activityReceiverModel);
			
			}
		}
		return activityReceiverModels;
	}
	
}
