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

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.blueland.bpm.common.util.DateUtil;
import com.blueland.bpm.engine.core.model.ActivityDefinitionModel;
import com.blueland.bpm.engine.core.model.ActivityInstanceModel;
import com.blueland.bpm.engine.core.model.ProcessDefinitionModel;
import com.blueland.bpm.engine.core.model.ProcessInputModel;
import com.blueland.bpm.engine.core.model.ProcessInstanceModel;
import com.blueland.bpm.engine.util.JsonUtil;
import com.blueland.bpm.engine.util.WorkFlowContants;
import com.blueland.bpm.log.model.ProcessErrorLog;
import com.blueland.bpm.log.service.ProcessErrorLogManager;
/**
 * 流程自动运行Service
 * @version:  1.0
 * @author lw 
 */
@Service
public class AutoRunOneProcess extends AbstractServiceHelper {
	@Autowired
	ProcessDefinitionService processDefinitionService;
	@Autowired
	private ProcessErrorLogManager processErrorLogManager;
	@Autowired
	ProcessExecuteServiceFacde processExecuteService;
	@Autowired
	ProcessInstanceService processInstanceService;
	// test_pt普通流程,test_expall 测试条件网关,testparentflow,测试父子流程,testParallelGateway:测试并行网关啊,test_neiqiansubflow内嵌子流程
	  String procDefKey = "test_neiqiansubflow";
	  String procTitle = "测试" + procDefKey;
	  String procStartUserId = "1001220126000600001";
	  String appId = "DEMO_SYS";
	
	public ProcessInstanceModel autoRunOneProcess(String procDefKey,String procStartUserId,String appId) {
		this.procDefKey = procDefKey;
		this.procStartUserId = procStartUserId;
		this.appId = appId;
		this.procTitle = "自动化模拟测试流程:" + procDefKey+DateUtil.convertDateToString("yyyyMMdd-HH:mm:ss", new Date());
		ProcessInputModel processInputModel = buildProcessInputModel();
		processInputModel.setWf_curComment("意见:"+processInputModel.getWf_curActDefName()+":"+new java.util.Random().nextInt());
		Map<String, Object> resultData = processExecuteService
				.nextExecute(processInputModel);
		ProcessInstanceModel processInstanceModel = (ProcessInstanceModel) resultData
				.get("processInstanceModel");
		next(resultData,new HashMap<String,ActivityInstanceModel>());
		return processInstanceModel;
	}
	
	
	public ProcessInstanceModel autoRunByLog(String procInstId) {
		ProcessErrorLog params=new ProcessErrorLog();
		params.setProcessInstanceId(procInstId);
		params.setProcessLogLevel("info");
		params.setSortColumns(" PELOG_CREATE_TIME");
		List<ProcessErrorLog> processErrorLogs=processErrorLogManager.findByExample(params);
		ProcessInstanceModel curtProcessInstanceModel =null;
		for (ProcessErrorLog processErrorLog : processErrorLogs) {
			ProcessInputModel processInputModel=(ProcessInputModel) JsonUtil.convertToBean(processErrorLog.getProcessMsg(), ProcessInputModel.class);
			if(!processErrorLog.getActionType().equals("lauch_save_process")) {
				processInputModel.setWf_procInstId(curtProcessInstanceModel.getProcInstId());
				List<ActivityInstanceModel> nextActivitys=curtProcessInstanceModel.getNextActivity();
				ActivityInstanceModel curActivityInstanceModel=null;
				for (ActivityInstanceModel activityInstanceModel : nextActivitys) {
					if(activityInstanceModel.getActDefId().equals(processInputModel.getWf_curActDefId())&&activityInstanceModel.getReceiverUserId().equals(processInputModel.getWf_sendUserId())){
						curActivityInstanceModel=activityInstanceModel;
						break;
					}
				}
				processInputModel.setWf_curActInstId(curActivityInstanceModel.getActInstId());
			}
			Map<String, Object> resultData = processExecuteService
					.nextExecute(processInputModel);
			curtProcessInstanceModel = (ProcessInstanceModel) resultData
					.get("processInstanceModel");
			
		}
		return curtProcessInstanceModel;
	}

	public void next(Map<String, Object> resultData,Map<String,ActivityInstanceModel> taskIds) {
		ProcessInstanceModel processInstanceModel = (ProcessInstanceModel) resultData
				.get("processInstanceModel");
		if(processInstanceModel==null){
			return;
		}
		List<ActivityInstanceModel> nextActInsts = processInstanceService.getTopProcessAllTasks(processInstanceModel.getTopProcInstId());
		if(nextActInsts==null||nextActInsts.isEmpty()){
			return;
		}
		for (ActivityInstanceModel nextActInst : nextActInsts) {
			/*	if(taskIds.containsKey(nextActInst.getActInstId())){
				continue;
			}*/
			try{
			if(processInstanceService.getTask(nextActInst.getActInstId())==null){
				return;
			}
			}catch(Exception e){return;}
			ProcessInputModel processInputModel = buildProcessInputModel();
			List<ActivityDefinitionModel> activityDefinitionModels=processDefinitionService.getNextActivity(nextActInst.getProcInstId(), nextActInst.getProcDefId(), nextActInst.getActDefId(), new HashMap());
			for (int i=0;i<activityDefinitionModels.size() ; i++) {
				ActivityDefinitionModel activityDefinitionModel=activityDefinitionModels.get(i);
				if(activityDefinitionModel.getActDefId().equals(nextActInst.getPrevActDefId())){
					ActivityInstanceModel historyTask=processInstanceService.getHistoryTask(nextActInst.getPrevActInstId());
					if(historyTask!=null&&historyTask.getProcInstId().equals(nextActInst.getProcInstId())){
					activityDefinitionModels.remove(i);
					i--;
					}
				}
			}
			processInputModel.setWf_nextActDefId(activityDefinitionModels.get(0).getActDefId());
			processInputModel.setWf_nextActDefType(activityDefinitionModels.get(0).getActType());
			processInputModel
					.setWf_actionType(WorkFlowContants.ACTION_TYPE_EXECUTE_ACTIVITY);
			processInputModel.setWf_procDefId(nextActInst.getProcDefId());
			processInputModel.setWf_procDefName(nextActInst.getProcDefName());
			processInputModel.setWf_curActDefId(nextActInst.getActDefId());
			processInputModel.setWf_curActDefName(nextActInst.getActDefName());
			processInputModel.setWf_curActInstId(nextActInst.getActInstId());
			processInputModel.setWf_procInstId(nextActInst.getProcInstId());
			processInputModel.setWf_sendUserId(nextActInst.getReceiverUserId());
			processInputModel.setWf_sendUserOrgId(nextActInst
					.getReceiverOrgId());
			processInputModel.setWf_curComment("意见1111:"+processInputModel.getWf_curActDefName()+":"+new java.util.Random().nextInt());
			Map<String, Object> tempResultData = processExecuteService
						.nextExecute(processInputModel);
			taskIds.put(nextActInst.getActDefId(),nextActInst);
			next(tempResultData,taskIds);
		
		}
	}

	public ProcessInputModel buildProcessInputModel() {
		ProcessDefinitionModel processDefinitionModel = processDefinitionService
				.getProcessDefBykey(procDefKey);
		ActivityDefinitionModel actDef=processDefinitionService.getStartActivity(processDefinitionModel.getProcDefId());
		ProcessInputModel processInputModel = new ProcessInputModel();
		processInputModel.setWf_procTitle(procTitle);
		processInputModel.setWf_appId(appId);
		processInputModel
				.setWf_procDefId(processDefinitionModel.getProcDefId());
		processInputModel.setWf_procDefKey(procDefKey);
		processInputModel
				.setWf_actionType(WorkFlowContants.ACTION_TYPE_LAUCH_PROCESS);
		processInputModel.setWf_procDefName(processDefinitionModel
				.getProcDefName());
		processInputModel.setWf_sendUserId(procStartUserId);
		processInputModel.setWf_sendUserOrgId("204300015350");
		processInputModel.setWf_businessKey(java.util.UUID.randomUUID().toString());
		processInputModel.setWf_curActDefId(actDef.getActDefId());
		processInputModel.setWf_curActDefName(actDef.getActDefName());
		processInputModel.setWf_curActDefType(actDef.getActType());
		processInputModel.setWf_uniteworkUrl("http://test");
		return processInputModel;
	}
}
