package com.highdatas.mdm.service.act.impl;

import com.highdatas.mdm.entity.TUser;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Service
public class HistoryServiceImpl extends BaseServiceImpl implements com.highdatas.mdm.service.act.HistoryService{
    @Autowired
    HistoryService historyService;
    @Autowired
    RepositoryService repositoryService;
    @Autowired
    TaskService taskService;



	public HistoricVariableInstance getRecentHistoryVariables(String key, String processId) {
		HistoricVariableInstance singleResult = historyService.createHistoricVariableInstanceQuery().processInstanceId(processId).variableName(key).orderByVariableName().desc().singleResult();
		return singleResult;
		
	}
	public List<HistoricVariableInstance> getHistoryVariables(String Key) {
		List<HistoricVariableInstance> list = historyService.createHistoricVariableInstanceQuery().variableName(Key).list();
		return list;
	}
	@Override
	public ArrayList<HistoricActivityInstance> getHistoryAction(String workflowId) {
		ArrayList<HistoricActivityInstance> result = new ArrayList<HistoricActivityInstance>();
		List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery().processInstanceId(workflowId).list();
		for (HistoricActivityInstance historicActivityInstance : list) {
			if (!historicActivityInstance.getActivityType().equalsIgnoreCase("exclusiveGateway")) {
				result.add(historicActivityInstance);
			}
		}
		return result;
		//resultPool.addValue(result);
	}	
	@Override
	public List<String> getMyHistotyApprove(String workflowId) {
        TUser onlineUser = getOnlineUser();
        ArrayList<String> result = new ArrayList<String>();
		List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery().processInstanceId(workflowId).list();
		for (HistoricActivityInstance historicActivityInstance : list) {
			if (!historicActivityInstance.getActivityType().equalsIgnoreCase("exclusiveGateway") ) {
				//TODO userType
//				if (onlineUser.getSysType().equalsIgnoreCase("DM") || (historicActivityInstance.getAssignee() != null && historicActivityInstance.getAssignee().equalsIgnoreCase(onlineUser.getUserId()))) {
//					result.add(historicActivityInstance.getProcessInstanceId());
//				}
			}
		}
		return result;
	}
	@Override
	public boolean isTaskFinished(String processId) {
		if (processId.isEmpty()) {
			return true;
		}
		
		HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processId).singleResult();
		Date endTime = instance.getEndTime();
		
		String endActivityId = instance.getEndActivityId();
		
		return (endActivityId!=null && !StringUtils.isEmpty(endActivityId) && endTime !=null);
	}
	@Override
	public void getTaskDetail(String processId) {
		String tableName = null;
		String userId = null;
		LinkedHashMap<String,String> variableMap = new LinkedHashMap<String, String>();
		List<HistoricVariableInstance> list = historyService.createHistoricVariableInstanceQuery().processInstanceId(processId).list();

		for (HistoricVariableInstance historicVariableInstance : list) {
			String variableName = historicVariableInstance.getVariableName();
			if (variableName.equalsIgnoreCase("tablename")) {
				tableName = (String) historicVariableInstance.getValue();
				continue;
			}
			if (variableName.equalsIgnoreCase("applyUserId")) {
				userId = (String) historicVariableInstance.getValue();
				continue;
			}
			variableMap.put(variableName, String.valueOf(historicVariableInstance.getValue()));
		}
		//TODO db

//		if (tableName != null && userId != null) {
//			NamedSQL namedSQL = NamedSQL.getInstance("getLineById");
//			namedSQL.setTableName(tableName);
//			namedSQL.setParam("fieldNameId", "user_id");
//			namedSQL.setParam("id", "'"+userId+"'");
//			Entity entity = SQLRunner.getEntity(namedSQL);
//			TableMeta tableMeta = entity.getTableMeta();
//			List<Field> fields = tableMeta.getFields();
//			for (Field field : fields) {
//				String fieldValue = entity.getString(field.getName());
//				variableMap.put(field.getName(), fieldValue);
//			}
//		}
		//resultPool.addValue(variableMap);
	}
	@Override
	public void getAllTask() {
		List<Map<String, String>> result = new ArrayList<Map<String, String>>();
		TUser user = getOnlineUser();
		List<HistoricProcessInstance> unFinishedTaskList = historyService.createHistoricProcessInstanceQuery().includeProcessVariables().list();
		Map<String, String> singleTask = null  ;

		for (HistoricProcessInstance historicProcessInstance : unFinishedTaskList) {
			String userId = historicProcessInstance.getStartUserId();
			if (user.getUserId().equalsIgnoreCase(userId)) {
					if (historicProcessInstance.getEndTime() == null) {
						Task Assigneetask = taskService.createTaskQuery().taskAssignee(userId).processInstanceId(historicProcessInstance.getId()).singleResult();
						if (Assigneetask != null) {
							ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(historicProcessInstance.getProcessDefinitionId()).singleResult();
							singleTask = packageTaskInfo( Assigneetask, processDefinition);
							 singleTask.put("status", "待办理");
						}
						Task CandiDateTask = taskService.createTaskQuery().taskCandidateUser(userId).processInstanceId(historicProcessInstance.getId()).singleResult();
						if (CandiDateTask != null) {
							ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(historicProcessInstance.getProcessDefinitionId()).singleResult();
							singleTask = packageTaskInfo( CandiDateTask, processDefinition);
							singleTask.put("status", "待接收");
						}
					}
					else {
						String processDefinitionId = historicProcessInstance.getProcessDefinitionId();
						ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
						singleTask = packageTaskInfo(new SimpleDateFormat("yyyy-MM-dd hh:mm"),historicProcessInstance, processDefinition);
						singleTask.put("status", "已结束");
					}
					
				result.add(singleTask);
			}
		}
		//resultPool.addValue("myUnFinishedTask", result, new TodoTaskWriter());
	}
	@Override
	public List<HistoricProcessInstance> getHistoryTask() {
		TUser user = getOnlineUser();
		List<HistoricTaskInstance> taskList = historyService.createHistoricTaskInstanceQuery().taskAssignee(user.getUserId()).list();
		HashSet<String> workflowIdSet = new HashSet<>();
		for (HistoricTaskInstance historicTaskInstance : taskList) {
			String processInstanceId = historicTaskInstance.getProcessInstanceId();
			workflowIdSet.add(processInstanceId);
		}

        List<HistoricProcessInstance> historicProcessInstances = historyService.createHistoricProcessInstanceQuery().processInstanceIds(workflowIdSet).list();
        return historicProcessInstances;

	}
	@Override
	public List<Map<String, String>> getMyRunTask() {
        TUser onlineUser = getOnlineUser();
        List<Map<String, String>> result = new ArrayList<Map<String, String>>();
		List<HistoricProcessInstance> unFinishedTaskList = historyService.createHistoricProcessInstanceQuery().includeProcessVariables().unfinished().list();
		Map<String, String> singleTask = null;

		for (HistoricProcessInstance historicProcessInstance : unFinishedTaskList) {
			String userId = historicProcessInstance.getStartUserId();
			if (onlineUser.getUserId().equalsIgnoreCase(userId)) {
				
					Task Assigneetask = taskService.createTaskQuery().taskAssignee(userId).processInstanceId(historicProcessInstance.getId()).singleResult();
					if (Assigneetask != null) {
						ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(historicProcessInstance.getProcessDefinitionId()).singleResult();
						singleTask = packageTaskInfo( Assigneetask, processDefinition);
						 singleTask.put("status", "待办理");
					}
					Task CandiDateTask = taskService.createTaskQuery().taskCandidateUser(userId).processInstanceId(historicProcessInstance.getId()).singleResult();
					if (CandiDateTask != null) {
						ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(historicProcessInstance.getProcessDefinitionId()).singleResult();
						singleTask = packageTaskInfo( CandiDateTask, processDefinition);
						 singleTask.put("status", "待接收");
					}
					
				result.add(singleTask);
			}
		}
		return result;
		//resultPool.addValue("myUnFinishedTask", result, new TodoTaskWriter());
	}
	
	public Map<String, String> packageTaskInfo(SimpleDateFormat sdf, HistoricProcessInstance historicProcessInstance, ProcessDefinition processDefinition) {
		TUser user = getOnlineUser();
		Map<String, String> singleTask = new HashMap<String, String>();
		singleTask.put("sid", user.getUserId());
		singleTask.put("id", historicProcessInstance.getId());
		singleTask.put("name", "已结束");
		singleTask.put("createTime", sdf.format(historicProcessInstance.getStartTime()));
		singleTask.put("pdname", processDefinition.getName());
		singleTask.put("pdversion", Integer.toString(processDefinition.getVersion()));
		singleTask.put("pid", historicProcessInstance.getId());
		
		return singleTask;
	}
	 
	public Map<String, String> packageTaskInfo(Task task, ProcessDefinition processDefinition) {
        Map<String, String> singleTask = new HashMap<String, String>();
        
        Map<String,Object> taskVariables = taskService.getVariables(task.getId());
        singleTask.put("sid", (String)taskVariables.get("applyUserId"));
		singleTask.put("id", task.getId());
		singleTask.put("name", task.getName());
		singleTask.put("isSuspension", String.valueOf(task.isSuspended()));
		singleTask.put("createTime", new SimpleDateFormat("yyyy-MM-dd hh:mm").format(task.getCreateTime()));
		singleTask.put("pdname", processDefinition.getName());
		singleTask.put("pdversion", Integer.toString(processDefinition.getVersion()));
		singleTask.put("pid", task.getProcessInstanceId());
		
		return singleTask;
	}
}