package com.blueland.bpm.manage.web;

import com.blueland.bpm.engine.config.model.ActivityInfoConfig;
import com.blueland.bpm.engine.config.model.DataObjectRelation;
import com.blueland.bpm.engine.config.service.ActivityInfoConfigManager;
import com.blueland.bpm.engine.config.service.DataObjectManager;
import com.blueland.bpm.engine.config.service.DataObjectRelationManager;
import com.blueland.bpm.engine.core.model.ProcessDefinitionModel;
import com.blueland.bpm.engine.core.service.ProcessDefinitionService;
import com.blueland.bpm.engine.core.service.ProcessModelService;
import com.blueland.bpm.engine.util.ProcessModelUtils;
import com.blueland.bpm.engine.util.WorkFlowContants;
import com.blueland.bpm.manage.util.BaseUser;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@Controller
@RequestMapping(value = "/actInfo/otherTask")
public class OtherTaskController extends BaseProcessController{
	// 默认多列排序,example: username desc,createTime asc
	protected static final String DEFAULT_SORT_COLUMNS = null;
	@Autowired
	private ActivityInfoConfigManager activityInfoConfigManager;
	@Autowired
	private ProcessDefinitionService processDefinitionService;
	@Autowired
	private DataObjectManager dataObjectManager;
	@Autowired
	private DataObjectRelationManager dataObjectRelationManager;
	@Autowired
	private ProcessModelService processModelService;
	private final String LIST_ACTION = "redirect:/otherTask/list.do";

	public OtherTaskController() {
	}



	/**
	 * 进入更新页面
	 **/
	@RequestMapping(value = "editScriptTaskView")
	public ModelAndView editScriptTaskView(HttpServletRequest request,
			ActivityInfoConfig params) {
		ModelAndView modelAndView=new ModelAndView("/actInfo/otherTask/editScriptTask");
		BpmnModel bpmnModel = processModelService
				.getBpmnModelByProcDefId(params.getProcessDefId());
		ScriptTask scriptTask = (ScriptTask) bpmnModel.getFlowElement(params.getActivityDefId());
		modelAndView.addObject("scriptTask",scriptTask);
		modelAndView.addObject("activityInfoConfig",params);
		return modelAndView;
	}
	
	/**
	 * 进入更新页面
	 **/
	@RequestMapping(value = "editScriptTask")
	@ResponseBody
	public String editScriptTask(HttpServletRequest request,
			ScriptTask scriptTask,ActivityInfoConfig params) {
		BpmnModel bpmnModel = processModelService
				.getBpmnModelByProcDefId(params.getProcessDefId());
		ScriptTask tempScriptTask = (ScriptTask) bpmnModel.getFlowElement(params.getActivityDefId());
		tempScriptTask.setScript(scriptTask.getScript());
		tempScriptTask.setScriptFormat(scriptTask.getScriptFormat());
		tempScriptTask.setDocumentation(scriptTask.getDocumentation());
		updateBpmnModel(bpmnModel, params.getProcessDefId(), true);
		return this.ACTION_SUCCESS;
	}


	/**
	 * 进入更新页面
	 **/
	@RequestMapping(value = "editServiceTaskView")
	public ModelAndView editServiceTaskView(HttpServletRequest request,
			ActivityInfoConfig params) {
		ModelAndView modelAndView=new ModelAndView("/actInfo/otherTask/editServiceTask");
		ActivityInfoConfig activityInfoConfig=activityInfoConfigManager.getActivityInfoConfig(params.getProcessDefId(), params.getActivityDefId());
		if(activityInfoConfig==null){
			return modelAndView;
		}
		BpmnModel bpmnModel = processModelService
				.getBpmnModelByProcDefId(params.getProcessDefId());
		ServiceTask serviceTask = (ServiceTask) bpmnModel.getFlowElement(activityInfoConfig.getActivityDefId());
		FieldExtension fieldExtension=ProcessModelUtils.findFieldExtension(serviceTask.getFieldExtensions(),"procDefIdText");
		String procDefIdText="";
		if(fieldExtension!=null){
			procDefIdText=fieldExtension.getStringValue();
			if(StringUtils.isNotEmpty(procDefIdText)){
				ProcessDefinitionModel throughProcDefModel=processDefinitionService.getProcessDef(procDefIdText);
				modelAndView.addObject("throughProcDefModel",throughProcDefModel);
			}
		}
		List<DataObjectRelation> dataObjectRelations=dataObjectRelationManager.findDataObjectRelationsByThroughProc(activityInfoConfig.getProcessDefId(), activityInfoConfig.getActivityDefId());
		modelAndView.addObject("procDefIdText",procDefIdText);
		modelAndView.addObject("serviceTask",serviceTask);
		modelAndView.addObject("activityInfoConfig",activityInfoConfig);
		modelAndView.addObject("dataObjectRelations",dataObjectRelations);
		return modelAndView;
	}
	
	/**
	 * 进入更新页面
	 **/
	@RequestMapping(value = "editServiceTask")
	@ResponseBody
	public String editServiceTask(HttpServletRequest request,
			ServiceTask serviceTask,String procDefIdText,ActivityInfoConfig params) {
		if(StringUtils.isEmpty(procDefIdText)){
			return this.ACTION_ERROR;
		}

		ActivityInfoConfig activityInfoConfig=activityInfoConfigManager.getActivityInfoConfig(params.getProcessDefId(), params.getActivityDefId());
		activityInfoConfig.setActivityDefType(BpmnXMLConstants.ELEMENT_TASK_SERVICE);
		activityInfoConfig.setActivityDefChildType(params.getActivityDefChildType());
		activityInfoConfig.setActivityDefDealType(params.getActivityDefDealType());
		activityInfoConfigManager.update(activityInfoConfig);
		BpmnModel bpmnModel = processModelService
				.getBpmnModelByProcDefId(params.getProcessDefId());
		ServiceTask tempServiceTask = (ServiceTask) bpmnModel.getFlowElement(params.getActivityDefId());
		tempServiceTask.setImplementationType("class");
		tempServiceTask.setType("");
		tempServiceTask.setImplementation("com.blueland.bpm.engine.core.listener.ThroughBizAppProcess");
		tempServiceTask.getFieldExtensions().clear();
				
		FieldExtension fieldExtension=new FieldExtension();
		fieldExtension.setFieldName("procDefIdText");
		fieldExtension.setStringValue(procDefIdText);
		tempServiceTask.getFieldExtensions().add(fieldExtension);
		tempServiceTask.setDocumentation(serviceTask.getDocumentation());
		//暂时必须是异常调用
		tempServiceTask.setAsynchronous(true);
		updateBpmnModel(bpmnModel, params.getProcessDefId(), false);
		return this.ACTION_SUCCESS;
	}
	
	
	
	

	/**
	 * 进入更新页面
	 **/
	@RequestMapping(value = "editCallActivityView")
	public ModelAndView editCallActivityView(HttpServletRequest request,
			ActivityInfoConfig params) {
		ModelAndView modelAndView=new ModelAndView("/actInfo/otherTask/editCallActivity");
		ActivityInfoConfig activityInfoConfig=activityInfoConfigManager.getActivityInfoConfig(params.getProcessDefId(), params.getActivityDefId());
		if(activityInfoConfig==null){
			return modelAndView;
		}
		BpmnModel bpmnModel = processModelService
				.getBpmnModelByProcDefId(params.getProcessDefId());
		CallActivity callActivity = (CallActivity) bpmnModel.getFlowElement(activityInfoConfig.getActivityDefId());
		String procDefKey=callActivity.getCalledElement();
		try{
		if(StringUtils.isNotEmpty(procDefKey)){
			ProcessDefinitionModel callProcDefModel=processDefinitionService.getProcessDefBykey(procDefKey);
			modelAndView.addObject("callProcDefModel",callProcDefModel);
		}}catch(Exception e){
			
		}
		modelAndView.addObject("callActivity",callActivity);
		modelAndView.addObject("activityInfoConfig",activityInfoConfig);
		modelAndView.addObject("dataInputAssociations",callActivity.getDataInputAssociations());
		return modelAndView;
	}
	
	/**
	 * 进入更新页面
	 **/
	@RequestMapping(value = "editCallActivity")
	@ResponseBody
	public String editCallActivity(HttpServletRequest request,
			CallActivity callActivity,ActivityInfoConfig params) {
		String procDefId=callActivity.getCalledElement();
		if(StringUtils.isEmpty(procDefId)){
			return this.ACTION_ERROR;
		}
		ActivityInfoConfig activityInfoConfig=activityInfoConfigManager.getActivityInfoConfig(params.getProcessDefId(), params.getActivityDefId());
		activityInfoConfig.setActivityDefType(BpmnXMLConstants.ELEMENT_CALL_ACTIVITY);
		activityInfoConfig.setActivityDefChildType(params.getActivityDefChildType());
		activityInfoConfig.setActivityDefDealType(params.getActivityDefDealType());
		activityInfoConfigManager.update(activityInfoConfig);
		BpmnModel bpmnModel = processModelService
				.getBpmnModelByProcDefId(params.getProcessDefId());
		CallActivity tempCallActivity = (CallActivity) bpmnModel.getFlowElement(params.getActivityDefId());
		if(procDefId.indexOf(":")!=-1){	
			tempCallActivity.setCalledElement(procDefId.split(":")[0]);
		}
		
		tempCallActivity.setDocumentation(callActivity.getDocumentation());
		tempCallActivity.getInParameters().clear();
		tempCallActivity.getOutParameters().clear();
		ExtensionElement extensionAttribute=null;
		//把原来的属性,使用带activiti:前缀的属性,这样导入不会出现异常
		if(tempCallActivity.getExtensionElements().get(WorkFlowContants.ACTIVITY_DEF_CHILD_TYPE)!=null){
			tempCallActivity.getExtensionElements().remove(WorkFlowContants.ACTIVITY_DEF_CHILD_TYPE);
		}
		if(tempCallActivity.getExtensionElements().get(WorkFlowContants.PREX_ACTIVITY_DEF_CHILD_TYPE)!=null){
			extensionAttribute=(ExtensionElement) (tempCallActivity.getExtensionElements().get(WorkFlowContants.PREX_ACTIVITY_DEF_CHILD_TYPE).get(0));
			extensionAttribute.setElementText(params.getActivityDefChildType());
		}else{
			extensionAttribute=new ExtensionElement();
			extensionAttribute.setName(WorkFlowContants.PREX_ACTIVITY_DEF_CHILD_TYPE);
			extensionAttribute.setElementText(params.getActivityDefChildType());
			tempCallActivity.addExtensionElement(extensionAttribute);
		}
		if(params.getActivityDefChildType().equals(ActivityInfoConfig.ACTIVITY_DEF_CHILD_TYPE_THROUGH)){
			IOParameter dataAssociation1=new IOParameter();
			dataAssociation1.setSource(WorkFlowContants.WF_PROCESS_INPUT_VARIABLE_KEY);
			dataAssociation1.setTarget(WorkFlowContants.WF_PROCESS_INPUT_VARIABLE_KEY);
			IOParameter dataAssociation2=new IOParameter();
			dataAssociation2.setSource(WorkFlowContants.WF_FIELDS_KEY);
			dataAssociation2.setTarget(WorkFlowContants.WF_FIELDS_KEY);
			IOParameter dataAssociation3=new IOParameter();
			//流程贯穿数据变量
			dataAssociation3.setSource(WorkFlowContants.WF_THROUGH_BUSINESS_DATA_OBJECT_KEY);
			dataAssociation3.setTarget(WorkFlowContants.WF_THROUGH_BUSINESS_DATA_OBJECT_KEY);
			IOParameter dataAssociation4=new IOParameter();
			dataAssociation4.setSource(WorkFlowContants.WF_PRE_TASK_DEF_NAME_VAR_KEY);
			dataAssociation4.setTarget(WorkFlowContants.WF_PRE_TASK_DEF_NAME_VAR_KEY);
			IOParameter dataAssociation5=new IOParameter();
			dataAssociation5.setSource(WorkFlowContants.WF_PRE_TASK_ID_VAR_KEY);
			dataAssociation5.setTarget(WorkFlowContants.WF_PRE_TASK_ID_VAR_KEY);
			IOParameter dataAssociation6=new IOParameter();
			dataAssociation6.setSource(WorkFlowContants.WF_PRE_TASK_DEF_ID_VAR_KEY);
			dataAssociation6.setTarget(WorkFlowContants.WF_PRE_TASK_DEF_ID_VAR_KEY);
			tempCallActivity.getInParameters().add(dataAssociation1);
			tempCallActivity.getInParameters().add(dataAssociation2);
			tempCallActivity.getInParameters().add(dataAssociation3);
			tempCallActivity.getInParameters().add(dataAssociation4);
			tempCallActivity.getInParameters().add(dataAssociation5);
			tempCallActivity.getInParameters().add(dataAssociation6);
			tempCallActivity.getOutParameters().add(dataAssociation1);
			tempCallActivity.getOutParameters().add(dataAssociation2);
			tempCallActivity.getOutParameters().add(dataAssociation3);
			tempCallActivity.getOutParameters().add(dataAssociation4);
			tempCallActivity.getOutParameters().add(dataAssociation5);
			tempCallActivity.getOutParameters().add(dataAssociation6);
		}else{//内部子流程数据变量
			IOParameter dataAssociation1=new IOParameter();
			dataAssociation1.setSource(WorkFlowContants.WF_PROCESS_INPUT_VARIABLE_KEY);
			dataAssociation1.setTarget(WorkFlowContants.WF_PROCESS_INPUT_VARIABLE_KEY);
			IOParameter dataAssociation2=new IOParameter();
			dataAssociation2.setSource(WorkFlowContants.WF_FIELDS_KEY);
			dataAssociation2.setTarget(WorkFlowContants.WF_FIELDS_KEY);
			IOParameter dataAssociation3=new IOParameter();
			dataAssociation3.setSource(WorkFlowContants.WF_BUSINESS_DATA_OBJECT_KEY);
			dataAssociation3.setTarget(WorkFlowContants.WF_BUSINESS_DATA_OBJECT_KEY);
			IOParameter dataAssociation4=new IOParameter();
			dataAssociation4.setSource(WorkFlowContants.WF_PRE_TASK_DEF_NAME_VAR_KEY);
			dataAssociation4.setTarget(WorkFlowContants.WF_PRE_TASK_DEF_NAME_VAR_KEY);
			IOParameter dataAssociation5=new IOParameter();
			dataAssociation5.setSource(WorkFlowContants.WF_PRE_TASK_ID_VAR_KEY);
			dataAssociation5.setTarget(WorkFlowContants.WF_PRE_TASK_ID_VAR_KEY);
			IOParameter dataAssociation6=new IOParameter();
			dataAssociation6.setSource(WorkFlowContants.WF_PRE_TASK_DEF_ID_VAR_KEY);
			dataAssociation6.setTarget(WorkFlowContants.WF_PRE_TASK_DEF_ID_VAR_KEY);
			tempCallActivity.getInParameters().add(dataAssociation1);
			tempCallActivity.getInParameters().add(dataAssociation2);
			tempCallActivity.getInParameters().add(dataAssociation3);
			tempCallActivity.getInParameters().add(dataAssociation4);
			tempCallActivity.getInParameters().add(dataAssociation5);
			tempCallActivity.getInParameters().add(dataAssociation6);
			tempCallActivity.getOutParameters().add(dataAssociation1);
			tempCallActivity.getOutParameters().add(dataAssociation2);
			tempCallActivity.getOutParameters().add(dataAssociation3);
			tempCallActivity.getOutParameters().add(dataAssociation4);
			tempCallActivity.getOutParameters().add(dataAssociation5);
			tempCallActivity.getOutParameters().add(dataAssociation6);
		}
		//暂时必须是异常调用
		tempCallActivity.setAsynchronous(false);
		
		if (params.isMulti()) {
			if (tempCallActivity != null
					&& tempCallActivity.getLoopCharacteristics() == null) {
				MultiInstanceLoopCharacteristics multiInstance = new MultiInstanceLoopCharacteristics();
				multiInstance.setElementVariable(WorkFlowContants.ELEMENT_ASSIGNEE);
				multiInstance.setInputDataItem(WorkFlowContants.ELEMENT_ASSIGNEE_EL);
				multiInstance.setSequential(false);
				tempCallActivity.setLoopCharacteristics(multiInstance);
			}
		} else if (tempCallActivity != null
				&& tempCallActivity.getLoopCharacteristics() != null) {
			tempCallActivity.setLoopCharacteristics(null);
		}
		updateBpmnModel(bpmnModel, params.getProcessDefId(), false);
		return this.ACTION_SUCCESS;
	}
	

	@RequestMapping(value = "createCallActProperty")
	public ModelAndView createCallActProperty(DataObjectRelation dataObjectRelation) {
		ModelAndView modelAndView = new ModelAndView(
				"/actInfo/otherTask/property/create");
		modelAndView.addObject("dataObjectRelation", dataObjectRelation);
		return modelAndView;
	}
	@RequestMapping(value = "saveCallActProperty")
	@ResponseBody
	public String saveCallActProperty(HttpServletRequest request,DataObjectRelation dataObjectRelation) {
		boolean result=false;
		dataObjectRelation.getDataObject().setObjName(dataObjectRelation.getDataObject().getObjKey());
		dataObjectRelation.getDataObject().setTenantId(BaseUser.getInstance().getLoginUserAppId(request));
		dataObjectRelationManager.save(dataObjectRelation);
		result=true;
		return result?this.ACTION_SUCCESS:this.ACTION_ERROR;
	}
	
	@RequestMapping(value = "editCallActProperty")
	public ModelAndView editCallActProperty(String dorId) {
		ModelAndView modelAndView = new ModelAndView(
				"/actInfo/otherTask/property/edit");
		DataObjectRelation dataObjectRelation = (DataObjectRelation)dataObjectRelationManager.getById(dorId);
		modelAndView.addObject("dataObjectRelation", dataObjectRelation);
		return modelAndView;
	}
	
	@RequestMapping(value = "updateCallActProperty")
	@ResponseBody
	public String updateCallActProperty(DataObjectRelation dataObjectRelation) {
		boolean result=false;
		dataObjectRelation.getDataObject().setObjName(dataObjectRelation.getDataObject().getObjKey());
		dataObjectRelationManager.update(dataObjectRelation);
		result=true;
		return result?this.ACTION_SUCCESS:this.ACTION_ERROR;
	}
	
	@RequestMapping(value = "deleteCallActProperty")
	@ResponseBody
	public String deleteCallActProperty(String processDefId,String id,String[] dorIds) {
		boolean result=false;
		for (String dorId : dorIds) {
			DataObjectRelation dataObjectRelation=dataObjectRelationManager.getById(dorId);
			if(dataObjectRelation!=null){
				dataObjectRelationManager.removeById(dorId);
				dataObjectManager.removeById(dataObjectRelation.getObjId());
			}
		}
		result=true;
		return result?this.ACTION_SUCCESS:this.ACTION_ERROR;
	}
	
}
