package com.blueland.ebpm.rest;

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

import org.activiti.engine.impl.persistence.entity.HistoricProcessInstanceEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.blueland.bpm.engine.config.model.ActivityInfoConfig;
import com.blueland.bpm.engine.core.model.ActivityDefinitionModel;
import com.blueland.bpm.engine.core.model.ActivityInstanceModel;
import com.blueland.bpm.engine.core.model.BusinessDataObject;
import com.blueland.bpm.engine.core.model.ExceptionErrorCode;
import com.blueland.bpm.engine.core.model.ProcessDefinitionModel;
import com.blueland.bpm.engine.core.model.ProcessLogModel;
import com.blueland.bpm.engine.core.service.ProcessInstanceService;
import com.blueland.bpm.engine.core.service.ProcessOperateFacade;
import com.blueland.bpm.engine.core.service.ProcessTraceService;
import com.blueland.ebpm.bean.ActivityDefinitionBean;
import com.blueland.ebpm.bean.ActivityInstanceBean;
import com.blueland.ebpm.bean.ActivityOpBean;
import com.blueland.ebpm.bean.BeansBuilder;
import com.blueland.ebpm.bean.ProcessDefinitionBean;
import com.blueland.ebpm.bean.ProcessInstanceBean;
import com.blueland.ebpm.bean.ProcessLogBean;
import com.blueland.ebpm.exception.RestException;

@RestController
public class SpecialController {
	
	@Autowired
	private ProcessOperateFacade processOperateFacase;
	
	@Autowired
	private ProcessInstanceService processInstanceService;
	
	@Autowired
	private ProcessTraceService processTraceService;
	
	@Autowired
	private BeansBuilder beansBuilder;

	@RequestMapping(value = "/special/newflowinfo",  produces = "application/json;charset=UTF-8")
	public Map<String, Object> getNewFlowInfo(@RequestParam String procDefId,
			@RequestParam String userId, @RequestParam String userOrgId) {
		Map<String, Object> tmpResult = processOperateFacase.getProcessStartDetail(procDefId, userId, userOrgId);
		Map<String, Object> result = new HashMap<String, Object>();
		ProcessDefinitionBean procDef =  beansBuilder.build((ProcessDefinitionModel)tmpResult.get("processDefinition"));
		ActivityDefinitionBean curActDef = beansBuilder.build((ActivityDefinitionModel)tmpResult.get("curActivity"));
		result.put("procDef", procDef);
		result.put("curActDef", curActDef);
		return result;
	}

	@RequestMapping(value = "/special/todoflowinfo", method = RequestMethod.GET, produces = "application/json; charset=UTF-8")
	public Map<String, Object> getTodoFlowInfo(@RequestParam String curActInstId, @RequestParam String userId, @RequestParam String userOrgId) {
		Map<String, Object> result = new HashMap<String, Object>();
 		ActivityInstanceModel actInst = processInstanceService.getTask(curActInstId);
		if(actInst == null) {
			throw new RestException(ExceptionErrorCode.B2052.name(), "activity instance not found, id=" + curActInstId);
		}
		
		Map<String, Object> tmpResult = processOperateFacase.getProcessToDoDetail(actInst.getProcDefId(), actInst.getProcInstId(),
				curActInstId, actInst.getActDefId(), userId, userOrgId);
		Map<String, Object> tmpLogs = processTraceService.getHisTaskLog(actInst.getProcInstId());
		ActivityDefinitionModel actDef = (ActivityDefinitionModel)tmpResult.get("curActivity");
		ActivityInfoConfig config = actDef.getActivityInfoConfig();
		
		ProcessDefinitionBean procDef = beansBuilder.build((ProcessDefinitionModel)tmpResult.get("processDefinition"));
		ProcessInstanceBean procInst = beansBuilder.build((HistoricProcessInstanceEntity)tmpResult.get("processInstance"));
		ActivityDefinitionBean curActDef = beansBuilder.build(actDef);
		List<ActivityOpBean> actOppowers = beansBuilder.buildActOpList(config.getActivityOperatePowers());
		ActivityInstanceBean curActInst = beansBuilder.build((ActivityInstanceModel)tmpResult.get("task"));
		BusinessDataObject dataObject = (BusinessDataObject) processInstanceService.getBusinessDataObject(procInst.getProcInstId());
		List<ProcessLogBean> procLogs = beansBuilder.buildProcessLogList((List<ProcessLogModel>)tmpLogs.get("processDetailLogs"));
		
		
		result.put("procDef", procDef);
		result.put("procInst", procInst);
		result.put("curActDef", curActDef);
		result.put("actOppowers", actOppowers);
		result.put("curActInst", curActInst);
		result.put("dataObject", dataObject);
		result.put("procLogs", procLogs);
		
		return result;
	}
	
	@RequestMapping(value = "/special/zaibanflowinfo", method = RequestMethod.GET, produces = "application/json; charset=UTF-8")
	public Map<String, Object> getZaibanFlowInfo(@RequestParam String curActInstId, @RequestParam String userId, @RequestParam String userOrgId) {
		Map<String, Object> result = new HashMap<String, Object>();
 		ActivityInstanceModel actInst = processInstanceService.getHistoryTask(curActInstId);
		if(actInst == null) {
			throw new RestException(ExceptionErrorCode.B2052.name(), "activity instance not found, id=" + curActInstId);
		}
		
		Map<String, Object> tmpResult = processOperateFacase.getProcessZaibanDetail(actInst.getProcDefId(), actInst.getProcInstId(),
				curActInstId, actInst.getActDefId(), userId, userOrgId);
		Map<String, Object> tmpLogs = processTraceService.getHisTaskLog(actInst.getProcInstId());
		ActivityDefinitionModel actDef = (ActivityDefinitionModel)tmpResult.get("curActivity");
		ActivityInfoConfig config = actDef.getActivityInfoConfig();
		
		ProcessDefinitionBean procDef = beansBuilder.build((ProcessDefinitionModel)tmpResult.get("processDefinition"));
		ProcessInstanceBean procInst = beansBuilder.build((HistoricProcessInstanceEntity)tmpResult.get("processInstance"));
		ActivityDefinitionBean curActDef = beansBuilder.build(actDef);
		List<ActivityOpBean> actOppowers = beansBuilder.buildActOpList(config.getActivityOperatePowers());
		ActivityInstanceBean curActInst = beansBuilder.build((ActivityInstanceModel)tmpResult.get("task"));
		BusinessDataObject dataObject = (BusinessDataObject) processInstanceService.getBusinessDataObject(procInst.getProcInstId());
		List<ProcessLogBean> procLogs = beansBuilder.buildProcessLogList((List<ProcessLogModel>)tmpLogs.get("processDetailLogs"));
		
		
		result.put("procDef", procDef);
		result.put("procInst", procInst);
		result.put("curActDef", curActDef);
		result.put("actOppowers", actOppowers);
		result.put("curActInst", curActInst);
		result.put("dataObject", dataObject);
		result.put("procLogs", procLogs);
		
		return result;
	}
	
	@RequestMapping(value = "/special/finishflowinfo", method = RequestMethod.GET, produces = "application/json; charset=UTF-8")
	public Map<String, Object> getFinishFlowInfo(@RequestParam String procInstId, @RequestParam String userId, @RequestParam String userOrgId) {
		Map<String, Object> result = new HashMap<String, Object>();
		Map<String, Object> tmpResult = processOperateFacase.getProcessFinishDetail(procInstId, userId, userOrgId);
		Map<String, Object> tmpLogs = processTraceService.getHisTaskLog(procInstId);
		
		ActivityDefinitionModel actDef = (ActivityDefinitionModel)tmpResult.get("curActivity");
		ActivityInfoConfig config = actDef.getActivityInfoConfig();
		
		ProcessDefinitionBean procDef = beansBuilder.build((ProcessDefinitionModel)tmpResult.get("processDefinition"));
		ProcessInstanceBean procInst = beansBuilder.build((HistoricProcessInstanceEntity)tmpResult.get("processInstance"));
		ActivityDefinitionBean curActDef = beansBuilder.build(actDef);
		List<ActivityOpBean> actOppowers = beansBuilder.buildActOpList(config.getActivityOperatePowers());
		ActivityInstanceBean curActInst = beansBuilder.build((ActivityInstanceModel)tmpResult.get("task"));
		BusinessDataObject dataObject = (BusinessDataObject) processInstanceService.getBusinessDataObject(procInstId);
		List<ProcessLogBean> procLogs = beansBuilder.buildProcessLogList((List<ProcessLogModel>)tmpLogs.get("processDetailLogs"));
		
		result.put("procDef", procDef);
		result.put("procInst", procInst);
		result.put("curActDef", curActDef);
		result.put("actOppowers", actOppowers);
		result.put("curActInst", curActInst);
		result.put("dataObject", dataObject);
		result.put("procLogs", procLogs);
		
		
		return result;
	}
}
