package com.blueland.bpm.manage.service;

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.engine.core.model.ProcessInstanceModel;
import com.blueland.bpm.engine.core.service.ProcessInstanceService;
import com.blueland.bpm.engine.util.BaseSpringJdbcDao;

import groovy.util.logging.Slf4j;

/**
 * @作者     dsl
 * @创建时间  2019年12月09日
 * @说明     维护流程结束，重新退回最后一个环节，让流程可以重新走
 */
@Slf4j
@Service
public class ProcessRestoreService extends BaseSpringJdbcDao<String,String>{
	@Autowired
	private ProcessInstanceService processInstanceService;	

	/**
	 * 流程办结，恢复流程
	 */
	public Map<String, Object> processRestore(String procInstId) {
		Map<String,Object> result =  new HashMap<String, Object>();
		boolean flag = false;
		String msg = "操作失败!";
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("procInstId", procInstId);
		// 1、根据流程实例id获取流程任务数据
		ProcessInstanceModel procInstModel = processInstanceService.getProcessInstanceById(procInstId);
		// 判断非主流程
		if (!procInstModel.getTopProcInstId().equals(procInstId)) {
			msg="选择的流程为子流程，不能恢复！";
		    result.put("flag", flag);
		    result.put("msg", msg);
			return result;
		}
		// 判断状态不等于办结
		if ("5".equals(procInstModel.getProcState())) {
			return this.delBanJie(procInstId);
		}else if("3".equals(procInstModel.getProcState())){
			return this.delZuoFei(procInstId);
		}else{
			msg="该流程还未办结，不能恢复！";
		    result.put("flag", flag);
		    result.put("msg", msg);
			return result;
		}
		
	}
	/**
	 * 处理作废流程恢复
	 * @param procInstId
	 * @return
	 */
	private Map<String, Object> delZuoFei(String procInstId) {
		Map<String,Object> result =  new HashMap<String, Object>();
		boolean flag = false;
		String msg = "操作失败!";
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("procInstId", procInstId);
		String findTaskListSql = "select *from ACT_HI_TASKINST a where a.proc_inst_id_ = :procInstId order by start_time_ desc";
		List<Map<String, Object>> list = this.namedParameterJdbcTemplate.queryForList(findTaskListSql, params);
		if (!(list != null && list.size() > 0)) {
			msg="未找到该任务！";
		    result.put("flag", flag);
		    result.put("msg", msg);
			return result;
		}
		String taskId = list.get(0).get("id_").toString();
		Map<String, Object> taskParams = new HashMap<String, Object>();
		taskParams.put("taskId", taskId);
		Map<String, Object> procInstAndtaskParams = new HashMap<String, Object>();
		procInstAndtaskParams.put("taskId", taskId);
		procInstAndtaskParams.put("procInstId", procInstId);
		//插入任务对象
		String updateAct = "update ACT_HI_ACTINST aat set aat.end_time_=null,aat.duration_=null  where aat.proc_inst_id_ = :procInstId and aat.TASK_ID_= :taskId";
		String updateTask = "update ACT_HI_TASKINST tt set tt.action_type='execute_activity',tt.claim_time_=null,tt.description_=null,tt.end_time_=null,tt.duration_=null,tt.delete_reason_=null  where tt.proc_inst_id_ = :procInstId and id_= :taskId";
		String insertActTask ="insert into ACT_RU_TASK";
		insertActTask+=" (ID_, REV_, NAME_, PARENT_TASK_ID_, DESCRIPTION_, PRIORITY_, CREATE_TIME_,  OWNER_, ASSIGNEE_, DELEGATION_, EXECUTION_ID_, PROC_INST_ID_, PROC_DEF_ID_, TASK_DEF_KEY_,  DUE_DATE_, CATEGORY_, SUSPENSION_STATE_, TENANT_ID_, FORM_KEY_,PROC_TITLE,SENDER, PRE_TASK_DEF_KEY,PRE_TASK_DEF_NAME,PRE_TASK_ID,ACTION_TYPE,SEND_USER_NAME,SENDER_ORG_ID,SENDER_ORG_NAME,ASSIGNEE_USER_NAME,ASSIGNEE_ORG_ID,ASSIGNEE_ORG_NAME,ASSIGNEE_USER_ID,SEND_USER_ID,PROC_DEF_NAME)";  
		insertActTask+=" select ID_, 1, NAME_, PARENT_TASK_ID_,DESCRIPTION_, PRIORITY_, START_TIME_,  OWNER_, ASSIGNEE_, null, PROC_INST_ID_, PROC_INST_ID_, PROC_DEF_ID_, TASK_DEF_KEY_,  DUE_DATE_, CATEGORY_, 1, TENANT_ID_, FORM_KEY_,PROC_TITLE,SENDER, PRE_TASK_DEF_KEY,PRE_TASK_DEF_NAME,PRE_TASK_ID,ACTION_TYPE,SEND_USER_NAME,SENDER_ORG_ID,SENDER_ORG_NAME,ASSIGNEE_USER_NAME,ASSIGNEE_ORG_ID,ASSIGNEE_ORG_NAME,ASSIGNEE_USER_ID,SEND_USER_ID,PROC_DEF_NAME";
		insertActTask+=" from ACT_HI_TASKINST a where a.id_= :taskId";
		//修改流程状态
		String updateProc ="update  ACT_HI_PROCINST a set a.delete_reason_=null, a.end_time_=null,a.end_act_id_=null,proc_state=1 where a.proc_inst_id_ = :procInstId";
		//同步待办数据
		String updateHistory= "update t_unitework_history h set h.unite_status=1,h.unite_deal_time=null where h.unite_cur_actinstid= :taskId and h.unite_status=6";
		String insertTask = "insert into t_unitework_task";
	    insertTask+=" (unite_id, unite_title, unite_abstract, unite_content, unite_category, unite_rec_userid, unite_rec_username, unite_rec_orgid, unite_rec_orgname, unite_send_userid, unite_send_username, unite_send_orgid, unite_send_orgname, unite_status, unite_url, unite_tenant_id, unite_tenant_name, unite_send_time, unite_deal_time, unite_start_userid, unite_start_orgid, unite_start_username, unite_start_orgname, unite_start_time, unite_top_procinstid, unite_parent_procinstid, unite_procinstid, unite_procdefid, unite_procdefname, unite_cur_actinstid, unite_cur_actdefid, unite_cur_actdefname, unite_prev_actinstid, unite_prev_actdefid, unite_prev_actdefname, unite_service_code, unite_batch_id, unite_data_souce, unite_other_sys_deal_status, unite_procdefkey, unite_cur_actlimittime, unite_esb_messageid)";
	    insertTask+=" select unite_id, unite_title, unite_abstract, unite_content, unite_category, unite_rec_userid, unite_rec_username, unite_rec_orgid, unite_rec_orgname, unite_send_userid, unite_send_username, unite_send_orgid, unite_send_orgname, unite_status, unite_url, unite_tenant_id, unite_tenant_name, unite_send_time, unite_deal_time, unite_start_userid, unite_start_orgid, unite_start_username, unite_start_orgname, unite_start_time, unite_top_procinstid, unite_parent_procinstid, unite_procinstid, unite_procdefid, unite_procdefname, unite_cur_actinstid, unite_cur_actdefid, unite_cur_actdefname, unite_prev_actinstid, unite_prev_actdefid, unite_prev_actdefname, unite_service_code, unite_batch_id, unite_data_souce, unite_other_sys_deal_status, unite_procdefkey, unite_cur_actlimittime, unite_esb_messageid";
	    insertTask+=" from t_unitework_history h  where h.unite_cur_actinstid= :taskId and h.unite_status=1";
		
	    String deleteComment = "delete from  ACT_HI_COMMENT where proc_inst_id_ = :procInstId and task_id_= :taskId";
	    try {
			this.namedParameterJdbcTemplate.update(updateAct, procInstAndtaskParams);
			this.namedParameterJdbcTemplate.update(updateTask, procInstAndtaskParams);
			this.namedParameterJdbcTemplate.update(insertActTask, taskParams);
			this.namedParameterJdbcTemplate.update(updateProc, params);
			this.namedParameterJdbcTemplate.update(updateHistory, taskParams);
			this.namedParameterJdbcTemplate.update(insertTask, taskParams);
			this.namedParameterJdbcTemplate.update(deleteComment, procInstAndtaskParams);
		} catch (Exception e) {
			log.error("processRestore error ,procInstId:" + procInstId, e);
			msg="恢复数据异常，请查看后台日志";
		    result.put("flag", flag);
		    result.put("msg", msg);
			return result;
		}
		flag=true;
		msg="操作成功！";
		result.put("flag", flag);
		result.put("msg", msg);
		return result;
	}
	/**
	 * 处理办结流程恢复
	 * @param procInstId
	 * @return
	 */
	private Map<String, Object> delBanJie(String procInstId) {
		Map<String,Object> result =  new HashMap<String, Object>();
		boolean flag = false;
		String msg = "操作失败!";
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("procInstId", procInstId);
		String findTaskListSql = "select * from ACT_HI_TASKINST a where a.proc_inst_id_ = :procInstId order by start_time_ desc";
		List<Map<String, Object>> list = this.namedParameterJdbcTemplate.queryForList(findTaskListSql, params);
		if (!(list != null && list.size() > 0)) {
			msg="未找到该任务！";
		    result.put("flag", flag);
		    result.put("msg", msg);
			return result;
		}
		String taskId = list.get(0).get("id_").toString();
		Map<String, Object> taskParams = new HashMap<String, Object>();
		taskParams.put("taskId", taskId);
		Map<String, Object> procInstAndtaskParams = new HashMap<String, Object>();
		procInstAndtaskParams.put("taskId", taskId);
		procInstAndtaskParams.put("procInstId", procInstId);
		// 2、插入执行路径
		String insertExe = "insert into ACT_RU_EXECUTION";
		insertExe += " (ID_, REV_, PROC_INST_ID_, BUSINESS_KEY_, PROC_DEF_ID_, ACT_ID_,  IS_ACTIVE_, IS_CONCURRENT_, IS_SCOPE_,IS_EVENT_SCOPE_, PARENT_ID_, SUPER_EXEC_, SUSPENSION_STATE_,  CACHED_ENT_STATE_, TENANT_ID_, NAME_,PROC_TITLE,TOP_PROCESS_INSTANCE_ID_)";
		insertExe += " select";
		insertExe += " EXECUTION_ID_, '1', PROC_INST_ID_, '', PROC_DEF_ID_, TASK_DEF_KEY_, 1, 0, 1, 0, NULL, NULL, 1, 2, tenant_id_, NULL,proc_title,PROC_INST_ID_";
		insertExe += " from ACT_HI_TASKINST a where a.id_ = :taskId";
		// 3、插入任务对象
		String insertTask = "insert into ACT_RU_TASK";
		insertTask += " (ID_, REV_, NAME_, PARENT_TASK_ID_, DESCRIPTION_, PRIORITY_, CREATE_TIME_,  OWNER_, ASSIGNEE_, DELEGATION_, EXECUTION_ID_, PROC_INST_ID_, PROC_DEF_ID_, TASK_DEF_KEY_,  DUE_DATE_, CATEGORY_, SUSPENSION_STATE_, TENANT_ID_, FORM_KEY_,PROC_TITLE,SENDER, PRE_TASK_DEF_KEY,PRE_TASK_DEF_NAME,PRE_TASK_ID,ACTION_TYPE,SEND_USER_NAME,SENDER_ORG_ID,SENDER_ORG_NAME,ASSIGNEE_USER_NAME,ASSIGNEE_ORG_ID,ASSIGNEE_ORG_NAME,ASSIGNEE_USER_ID,SEND_USER_ID,PROC_DEF_NAME)";
		insertTask += " select";
		insertTask += " ID_, 1, NAME_, PARENT_TASK_ID_,DESCRIPTION_, PRIORITY_, START_TIME_,  OWNER_, ASSIGNEE_, null, PROC_INST_ID_, PROC_INST_ID_, PROC_DEF_ID_, TASK_DEF_KEY_,  DUE_DATE_, CATEGORY_, 1, TENANT_ID_, FORM_KEY_,PROC_TITLE,SENDER, PRE_TASK_DEF_KEY,PRE_TASK_DEF_NAME,PRE_TASK_ID,ACTION_TYPE,SEND_USER_NAME,SENDER_ORG_ID,SENDER_ORG_NAME,ASSIGNEE_USER_NAME,ASSIGNEE_ORG_ID,ASSIGNEE_ORG_NAME,ASSIGNEE_USER_ID,SEND_USER_ID,PROC_DEF_NAME";
		insertTask += " from ACT_HI_TASKINST a where a.id_ = :taskId";
		// 4、删除最后一步
		String delLastStep = "delete  from act_hi_actinst a where a.proc_inst_id_ = :procInstId and act_type_='endEvent'";
		// 5、修改流程状态
		String updateProcessStatus = "update  ACT_HI_PROCINST a set a.end_time_=null,a.end_act_id_=null,proc_state=1 where a.proc_inst_id_ = :procInstId";
		// 6、插入act_ru_variable数据
		String insertRu = "insert into act_ru_variable";
		insertRu += " (id_, rev_, type_, name_, execution_id_, proc_inst_id_, task_id_, bytearray_id_, double_, long_, text_, text2_)";
		insertRu += " select id_, rev_, var_type_, name_, execution_id_, proc_inst_id_, null, bytearray_id_, double_, long_, text_, text2_";
		insertRu += " from act_hi_varinst a where a.proc_inst_id_ = :procInstId and task_id_= :taskId";
		// 7、同步待办数据
		String updateHistory = "update t_unitework_history h set h.unite_status=1,h.unite_deal_time=null where h.unite_cur_actinstid= :taskId";
		// 8 、插入数据到t_unitework_task
		String insertUniteTask = "insert into t_unitework_task";
		insertUniteTask += " (unite_id, unite_title, unite_abstract, unite_content, unite_category, unite_rec_userid, unite_rec_username, unite_rec_orgid, unite_rec_orgname, unite_send_userid, unite_send_username, unite_send_orgid, unite_send_orgname, unite_status, unite_url, unite_tenant_id, unite_tenant_name, unite_send_time, unite_deal_time, unite_start_userid, unite_start_orgid, unite_start_username, unite_start_orgname, unite_start_time, unite_top_procinstid, unite_parent_procinstid, unite_procinstid, unite_procdefid, unite_procdefname, unite_cur_actinstid, unite_cur_actdefid, unite_cur_actdefname, unite_prev_actinstid, unite_prev_actdefid, unite_prev_actdefname, unite_service_code, unite_batch_id, unite_data_souce, unite_other_sys_deal_status, unite_procdefkey, unite_cur_actlimittime, unite_esb_messageid)";
		insertUniteTask += " select unite_id, unite_title, unite_abstract, unite_content, unite_category, unite_rec_userid, unite_rec_username, unite_rec_orgid, unite_rec_orgname, unite_send_userid, unite_send_username, unite_send_orgid, unite_send_orgname, unite_status, unite_url, unite_tenant_id, unite_tenant_name, unite_send_time, unite_deal_time, unite_start_userid, unite_start_orgid, unite_start_username, unite_start_orgname, unite_start_time, unite_top_procinstid, unite_parent_procinstid, unite_procinstid, unite_procdefid, unite_procdefname, unite_cur_actinstid, unite_cur_actdefid, unite_cur_actdefname, unite_prev_actinstid, unite_prev_actdefid, unite_prev_actdefname, unite_service_code, unite_batch_id, unite_data_souce, unite_other_sys_deal_status, unite_procdefkey, unite_cur_actlimittime, unite_esb_messageid";
		insertUniteTask += " from t_unitework_history h  where h.unite_cur_actinstid=:taskId";
		// 9、修改ACT_HI_ACTINST环节时间
		String updateActTime = "update ACT_HI_ACTINST aat set aat.end_time_=null,aat.duration_=null  where aat.proc_inst_id_ = :procInstId and task_id_= :taskId ";
		// 10、修改ACT_HI_ACTINST修改环节时间
		String updateTaskTime = " update ACT_HI_TASKINST tt set tt.claim_time_=null,tt.end_time_=null,tt.duration_=null,tt.delete_reason_=null  where tt.proc_inst_id_ = :procInstId and tt.ID_= :taskId";
		// 11、删除意见
		String delComment = "delete from  ACT_HI_COMMENT where proc_inst_id_ = :procInstId and task_id_=:taskId";
		try {
			this.namedParameterJdbcTemplate.update(insertExe, taskParams);
			this.namedParameterJdbcTemplate.update(insertTask, taskParams);
			this.namedParameterJdbcTemplate.update(delLastStep, params);
			this.namedParameterJdbcTemplate.update(updateProcessStatus, params);
			this.namedParameterJdbcTemplate.update(insertRu, procInstAndtaskParams);
			this.namedParameterJdbcTemplate.update(updateHistory, taskParams);
			this.namedParameterJdbcTemplate.update(insertUniteTask, taskParams);
			this.namedParameterJdbcTemplate.update(updateActTime, procInstAndtaskParams);
			this.namedParameterJdbcTemplate.update(updateTaskTime, procInstAndtaskParams);
			this.namedParameterJdbcTemplate.update(delComment, procInstAndtaskParams);
		} catch (Exception e) {
			log.error("processRestore error ,procInstId:" + procInstId, e);
			msg="恢复数据异常，请查看后台日志";
		    result.put("flag", flag);
		    result.put("msg", msg);
			return result;
		}
		flag=true;
		msg="操作成功！";
		result.put("flag", flag);
		result.put("msg", msg);
		return result;
	}
	
}
