package com.gaowj.business.proctask;

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

import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ProcessDefinitionImpl;
import org.activiti.engine.impl.pvm.process.TransitionImpl;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.ibatis.session.RowBounds;

import com.gaowj.business.ProctaskBusiness;
import com.gaowj.business.exception.ActivitiException;
import com.gaowj.business.exception.BusinessException;
import com.gaowj.business.formmodels.formmodelsDAO;
import com.gaowj.business.formtable.formtableDAO;
import com.gaowj.business.procdefinition.procdefinitionDAO;
import com.gaowj.business.procinstance.procinstanceDAO;
import com.gaowj.business.util.Page;
import com.gaowj.business.util.PropUtil;
import com.gaowj.business.util.SessionUtil;
import com.gaowj.business.utils.ActivitiTools;
import com.gaowj.business.utils.model.ActivitiOptEnum;
import com.gaowj.business.utils.model.ActivitiResultEnum;

public class ProctaskBusinessImpl implements ProctaskBusiness {

	private TaskService taskService;

	private RuntimeService runtimeService;

	private procinstanceDAO procinstanceDAO;

	private procdefinitionDAO procdefinitionDAO;

	private formmodelsDAO formmodelsDAO;

	private formtableDAO formtableDAO;

	private HistoryService historyService;

	private RepositoryService repositoryService;

	public RuntimeService getRuntimeService() {
		return runtimeService;
	}

	public void setRuntimeService(RuntimeService runtimeService) {
		this.runtimeService = runtimeService;
	}

	public TaskService getTaskService() {
		return taskService;
	}

	public void setTaskService(TaskService taskService) {
		this.taskService = taskService;
	}

	public procinstanceDAO getProcinstanceDAO() {
		return procinstanceDAO;
	}

	public void setProcinstanceDAO(procinstanceDAO procinstanceDAO) {
		this.procinstanceDAO = procinstanceDAO;
	}

	public procdefinitionDAO getProcdefinitionDAO() {
		return procdefinitionDAO;
	}

	public void setProcdefinitionDAO(procdefinitionDAO procdefinitionDAO) {
		this.procdefinitionDAO = procdefinitionDAO;
	}

	public formmodelsDAO getFormmodelsDAO() {
		return formmodelsDAO;
	}

	public void setFormmodelsDAO(formmodelsDAO formmodelsDAO) {
		this.formmodelsDAO = formmodelsDAO;
	}

	public formtableDAO getFormtableDAO() {
		return formtableDAO;
	}

	public void setFormtableDAO(formtableDAO formtableDAO) {
		this.formtableDAO = formtableDAO;
	}

	public HistoryService getHistoryService() {
		return historyService;
	}

	public void setHistoryService(HistoryService historyService) {
		this.historyService = historyService;
	}

	public RepositoryService getRepositoryService() {
		return repositoryService;
	}

	public void setRepositoryService(RepositoryService repositoryService) {
		this.repositoryService = repositoryService;
	}

	@Override
	public Page<Map<String, Object>> list_proc_task(int pageNo, int pageSize, Map<String, Object> query) throws BusinessException {
		Page<Map<String, Object>> page = new Page<Map<String, Object>>();
		// 计算起始记录
		int pageStart = (pageNo - 1) * pageSize;
		TaskQuery taskQuery = taskService.createTaskQuery().taskCandidateUser(SessionUtil.getCode());
		page.setStart(pageStart);
		page.setLimit(pageSize);
		page.setCount((int) taskQuery.count());
		List<Task> list = taskQuery.orderByTaskCreateTime().desc().list();
		List<Map<String, Object>> items = new ArrayList<Map<String, Object>>();
		List<String> listInstanceId = new ArrayList<String>();
		List<Map<String, Object>> listInstance = null;
		if (list.size() > 0) {
			for (Task task : list) {
				Map<String, Object> map = new HashMap<String, Object>();
				items.add(map);
				map.put("CREATE_TIME", task.getCreateTime());
				map.put("EXECUTION_ID", task.getExecutionId());
				map.put("PROCESS_INSTANCE_ID", task.getProcessInstanceId());
				map.put("TASK_ID", task.getId());
				// listInstanceId.add(task.getExecutionId());
				listInstanceId.add(task.getProcessInstanceId());
			}

			Map<String, Object> query2 = new HashMap<String, Object>();
			query2.put("INSTANCE_ID_IN", listInstanceId);

			if (query.get("PROCDEFINITION_UUID") != null && !"".equals(query.get("PROCDEFINITION_UUID"))) {
				String procdefinitionUuid = query.get("PROCDEFINITION_UUID").toString();
				query.remove("PROCDEFINITION_UUID");
				// 通过流程定义id获取表名
				Map<String, Object> query3 = new HashMap<String, Object>();
				query3.put("UUID", procdefinitionUuid);
				String tableName = procdefinitionDAO.list_procde_finition(query3).get(0).get("TABLE_NAME").toString();
				query2.put("tableName", tableName);
				try {
					listInstance = procinstanceDAO.list_proc_instance(new RowBounds(pageStart, pageSize),query2);
				} catch (Exception e) {
					if (e.getMessage().indexOf("doesn't exist") != -1) {
						// 如果有XX不存在字样,说明当前需要查询的表不存在,则直接设置为空list
						listInstance = new ArrayList<Map<String, Object>>();
					}
				}
			} else {
				if(query.get("SERACH_DATA")!=null&&!"".equals(query.get("SERACH_DATA"))){
					query2.put("SERACH_DATA","%"+query.get("SERACH_DATA")+"%");
				}
				listInstance = procinstanceDAO.list_proc_instance_all(new RowBounds(pageStart, pageSize),query2);
			}

			outer: for (Map<String, Object> instance : listInstance) {
				for (Map<String, Object> map : items) {
					if (map.get("PROCESS_INSTANCE_ID").equals(instance.get("INSTANCE_ID"))) {
						instance.putAll(map);
						continue outer;
					}
				}
			}
		} else {
			// 如果activit中没有任务,则new一个空的list
			listInstance = new ArrayList<Map<String, Object>>();
		}
		page.setItems(listInstance);
		return page;
	}

	@Override
	public Map<String, Object> data_info(String businessId) throws BusinessException {
		Map<String, Object> info = new HashMap<String, Object>();
		Map<String, Object> query = new HashMap<String, Object>();
		query.put("BUSINESS_ID", businessId);
		List<Map<String, Object>> listProcinstance = procinstanceDAO.list_proc_instance_all(query);
		if (listProcinstance.size() > 0) {
			Map<String, Object> procinstance = listProcinstance.get(0);
			// 流程定义id
			String procDefinitionId = procinstance.get("PROC_DEFINITION_ID").toString();
			// 表单模板id
			String formModelId = procinstance.get("FORM_MODEL_ID").toString();
			// 根据表单模板id获取模板
			Map<String, Object> formModel = getFormModelById(formModelId);
			// 根据流程定义id获取存储业务数据的表
			String tableName = getBusinessTableNameByProcDefinitionId(procDefinitionId);
			// 根据业务数据的表名和业务id,查询业务数据
			Map<String, Object> businessData = getBusinessDataByBusinessTableAndBusinessId(tableName, businessId);
			// 填充返回数据
			info.put("FORM_MODEL", formModel);
			info.put("BUSINESS_DATA", businessData);
			info.put("PROCINSTANCE", procinstance);
		}
		return info;
	}

	private Map<String, Object> getFormModelById(String uuid) {
		Map<String, Object> query = new HashMap<String, Object>();
		query.put("UUID", uuid);
		return formmodelsDAO.list_form_models(query).get(0);
	}

	/**
	 * 根据流程定义id获取业务数据表的表名
	 * 
	 * @param procDefinitionId
	 * @return
	 */
	private String getBusinessTableNameByProcDefinitionId(String procDefinitionId) {
		Map<String, Object> query = new HashMap<String, Object>();
		query.put("UUID", procDefinitionId);
		return procdefinitionDAO.list_procde_finition(query).get(0).get("TABLE_NAME").toString();
	}

	private Map<String, Object> getBusinessDataByBusinessTableAndBusinessId(String tableName, String uuid) {
		Map<String, Object> query = new HashMap<String, Object>();
		query.put("UUID", uuid);
		query.put("tableName", tableName);
		query.put("lcyq_table_db", PropUtil.getValue("lcyq_table_db", "quartz_service", ""));
		return procinstanceDAO.list_proc_instance(query).get(0);
	}

	@Override
	public Map<String, Object> update(Map<String, Object> entity) throws ActivitiException, BusinessException {
		ActivitiResultEnum activitiResultEnum = ActivitiTools.save(entity, ActivitiOptEnum.SAVE);
		switch (activitiResultEnum) {
		case OK:
			break;
		default:
			throw new ActivitiException(activitiResultEnum.getMsg());
		}
		return entity;
	}

	@Override
	public Map<String, Object> updateToNext(Map<String, Object> entity) throws ActivitiException, BusinessException {
		ActivitiResultEnum activitiResultEnum = ActivitiTools.save(entity, ActivitiOptEnum.SAVE_AND_NEXT);
		switch (activitiResultEnum) {
		case OK:
			break;
		default:
			throw new ActivitiException(activitiResultEnum.getMsg());
		}
		return entity;
	}

	@Override
	public Map<String, Object> back(Map<String, Object> entity) throws BusinessException {
		ActivitiResultEnum activitiResultEnum = ActivitiTools.save(entity, ActivitiOptEnum.SAVE_AND_RALLBACK);
		switch (activitiResultEnum) {
		case OK:
			break;
		default:
			throw new ActivitiException(activitiResultEnum.getMsg());
		}
		return entity;
	}


}