/**
 * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.jeeplus.modules.act.web;

import com.jeeplus.common.persistence.Page;
import com.jeeplus.common.utils.Collections3;
import com.jeeplus.common.utils.DateUtils;
import com.jeeplus.common.web.BaseController;
import com.jeeplus.modules.act.entity.Act;
import com.jeeplus.modules.act.service.ActTaskService;
import com.jeeplus.modules.act.utils.ActUtils;
import com.jeeplus.modules.sys.entity.Role;
import com.jeeplus.modules.sys.entity.SysRoleActivity;
import com.jeeplus.modules.sys.entity.User;
import com.jeeplus.modules.sys.service.SystemService;
import com.jeeplus.modules.sys.utils.UserUtils;
import com.jeeplus.modules.workactivity.entity.WorkActivityProcess;
import com.jeeplus.modules.workactivity.service.WorkActivityProcessService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 流程个人任务相关Controller
 * @author jeeplus
 * @version 2013-11-03
 */
@Controller
@RequestMapping(value = "${adminPath}/act/task")
public class ActTaskController extends BaseController {

	@Autowired
	private ActTaskService actTaskService;
	@Autowired
	private WorkActivityProcessService workActivityProcessService;
	@Autowired
	private SystemService systemService;

	/**
	 * 获取待办列表
	 * @param act 流程定义标识
	 * @return
	 */
	@RequestMapping(value = {"todo", ""})
	public String todoList(Act act, HttpServletResponse response, Model model) throws Exception {

		System.out.println("act---------------"+act.toString());
		List<Act> list = actTaskService.todoList(act);
		model.addAttribute("list", list);


		if (UserUtils.getPrincipal().isMobileLogin()){
			return renderString(response, list);
		}
		return "modules/act/actTaskTodoList";
	}

	/**
	 * 获取已办任务
	 * @param act 流程定义标识
	 * @return
	 */
	@RequestMapping(value = "historic")
	public String historicList(Act act, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
		Page<Act> page = actTaskService.historicList(new Page<Act>(request, response), act);
		System.out.println("actHistoric"+act.toString());
		model.addAttribute("page", page);
		if (UserUtils.getPrincipal().isMobileLogin()){
			return renderString(response, page);
		}
		return "modules/act/actTaskHistoricList";
	}

	/**
	 * 获取流转历史列表
	 * @param startAct 开始活动节点名称
	 * @param endAct 结束活动节点名称
	 */
	@RequestMapping(value = "histoicFlow")
	public String histoicFlow(Act act, String startAct, String endAct, Model model){
		if (StringUtils.isNotBlank(act.getProcInsId())){
			WorkActivityProcess workActivityProcess = new WorkActivityProcess();
			workActivityProcess.setProcessInstanceId(act.getProcInsId());
			/*List<Act> histoicFlows = new ArrayList<>();
			List<Act> histoicFlowList = actTaskService.histoicFlowList(act.getProcInsId(), startAct, endAct);
			histoicFlows = getList(histoicFlowList);*/
			List<WorkActivityProcess> list = workActivityProcessService.findByProcInsId(workActivityProcess);
			workActivityProcess.setIsApproval("0");
			List<WorkActivityProcess> lists = workActivityProcessService.findByProcInsIdAudit(workActivityProcess);
			List<WorkActivityProcess> beginList = workActivityProcessService.findByProcInsIdAndIsApproval(workActivityProcess);
			List<Act> histoicFlows = new ArrayList<>();
			Date beginDate = new Date();
			String userName = "";
			Date endDate = new Date();
			if (beginList!=null && beginList.size()!=0){
				beginDate = beginList.get(0).getCreateDate();
				userName = beginList.get(0).getCreateBy().getName();
			}else {
				if (lists!=null && lists.size()!=0){
					beginDate = lists.get(lists.size()-1).getCreateDate();
				}
			}
			if (list!=null && list.size()!=0){
				endDate = list.get(list.size()-1).getUpdateDate();
			}


			if (list!=null && lists!=null && list.size()==0 && lists.size()==0){
				List<Act> histoicFlowList = actTaskService.histoicFlowList(act.getProcInsId(), startAct, endAct);
				histoicFlows = getList(histoicFlowList);
			}else {
				Act act1 = new Act();
				act1.setBeginDate(beginDate);
				act1.setEndDate(beginDate);
				act1.setTaskName("开始");
				act1.setComment("发起申请");
				act1.setDurationTime("0秒");
				if (StringUtils.isNotBlank(userName)){
					act1.setAssigneeName(userName);
				}else if(lists.size()!=0){
					act1.setAssigneeName(UserUtils.get(lists.get(lists.size()-1).getCreateBy().getId()).getName());
				}else if (list.size()!=0){
					act1.setAssigneeName(UserUtils.get(list.get(list.size()-1).getCreateBy().getId()).getName());
				}

				histoicFlows.add(act1);
				for (int i =0;i<list.size();i++){
					WorkActivityProcess activityProcess = list.get(i);
					Act a = new Act();
					if (activityProcess.getActivity() ==null){
						if (StringUtils.isNotBlank(userName)){
							a.setAssigneeName(userName);
						}else if (lists!=null && lists.size()!=0){
							a.setAssigneeName(UserUtils.get(lists.get(lists.size()-1).getCreateBy().getId()).getName());
						}else {
							a.setAssigneeName(UserUtils.get(list.get(list.size()-1).getCreateBy().getId()).getName());
						}
						if("销假申请".equals(activityProcess.getRemarks())||"续假申请".equals(activityProcess.getRemarks())){
							a.setTaskName("开始");
						}else{
							a.setTaskName("重申|撤销");
						}
					}else if (activityProcess.getActivity().getUser()!=null && StringUtils.isNotBlank(activityProcess.getActivity().getUser().getId())){
						String id = activityProcess.getActivity().getUser().getId();
						if ("1".equals(id)){
							a.setAssigneeName("负责人");
						}else {
							a.setAssigneeName(UserUtils.get(activityProcess.getActivity().getUser().getId()).getName());
						}
						a.setTaskName(activityProcess.getActivity().getName());
					}else{
						User user = new User();
						if (activityProcess.getUpdateBy()!=null && StringUtils.isNotBlank(activityProcess.getUpdateBy().getId())){
							user = UserUtils.get(activityProcess.getUpdateBy().getId());
						}
						SysRoleActivity role = activityProcess.getActivity().getRole();
						String buffer = UserUtils.getRoleActivityEnname(UserUtils.getSelectCompany().getId(),UserUtils.getUser());
						if (role.getEnname().contains(buffer.toString())){
							SysRoleActivity r = systemService.getRoleActivityByEnname(role.getEnname());
							if(r!=null&&!"".equals(r)){
								a.setRoleName(r.getName());
								a.setAssigneeName(user.getName());
							}
						}else {
							SysRoleActivity r = systemService.getRoleActivityByEnname(buffer+role.getEnname());
							if(r!=null&&!"".equals(r)){
								a.setRoleName(r.getName());
								a.setAssigneeName(user.getName());
							}else if(r==null&&"qyr".equals(role.getEnname())){
								a.setRoleName("签约人");
								a.setAssigneeName(user.getName());
							}else if(r==null&&"master".equals(role.getEnname())){
								a.setRoleName("负责人");
								a.setAssigneeName(user.getName());
							}else if(r==null&&"sqr".equals(role.getEnname())){
								a.setRoleName("申请人");
								a.setAssigneeName(user.getName());
							}
						}
						a.setTaskName(activityProcess.getActivity().getName());
					}

					a.setComment(activityProcess.getRemarks());
					if (compareDate(beginDate,activityProcess.getUpdateDate())!=0) {
						if (i==0){
							a.setBeginDate(beginDate);
							a.setEndDate(activityProcess.getUpdateDate());
						}else {
							a.setBeginDate(list.get(i-1).getUpdateDate());
							a.setEndDate(activityProcess.getUpdateDate());
						}
					}
					if (a.getBeginDate()!=null && a.getEndDate()!=null){
						String durationTime = "";
						long time = 0;
						if (a.getEndDate().getTime()>a.getBeginDate().getTime()){
							time = a.getEndDate().getTime() - a.getBeginDate().getTime();
						}else {
							time = a.getBeginDate().getTime() - a.getEndDate().getTime() ;
						}

						time /= 1000;
						long day = time/(24*3600);
						if (day != 0){
							durationTime = day+"天";
						}
						time = time % (24*3600);
						long hour = time/3600;
						if (hour != 0){
							durationTime += hour+"小时";
						}
						time = time % 3600;
						long min = time/60;
						if (min != 0){
							durationTime += min+"分";
						}
						time = time % 60;
						long sec = time;
						if (sec != 0){
							durationTime += sec+"秒";
						}
						a.setDurationTime(durationTime);
					}
					histoicFlows.add(a);
				}
				for (int i =0;i<lists.size();i++){
					WorkActivityProcess activityProcess = lists.get(i);
					Act a = new Act();
					if (activityProcess.getActivity() ==null) {
						if (StringUtils.isNotBlank(userName)) {
							a.setAssigneeName(userName);
						} else {
							a.setAssigneeName(UserUtils.get(lists.get(lists.size() - 1).getCreateBy().getId()).getName());
						}
						if("销假申请".equals(activityProcess.getRemarks())||"续假申请".equals(activityProcess.getRemarks())){
							a.setTaskName("开始");
						}else{
							a.setTaskName("重申|撤销");
						}
					}else if (activityProcess.getActivity().getUser()!=null && StringUtils.isNotBlank(activityProcess.getActivity().getUser().getId())){
						String id = activityProcess.getActivity().getUser().getId();
						if ("1".equals(id)){
							a.setRoleName("负责人");
						}else {
							a.setAssigneeName(UserUtils.get(activityProcess.getActivity().getUser().getId()).getName());
						}
						a.setTaskName(activityProcess.getActivity().getName());
					}else{
						SysRoleActivity role = activityProcess.getActivity().getRole();
						String buffer = UserUtils.getRoleActivityEnname(UserUtils.getSelectCompany().getId(),UserUtils.getUser());
						if (activityProcess.getProcessUserList()!=null && activityProcess.getProcessUserList().size()!=0){
							a.setAssigneeName(Collections3.extractToString(activityProcess.getProcessUserList(), "name", ","));
						}
						if("master".equals(role.getEnname())){
							a.setRoleName("负责人");
						}else if("qyr".equals(role.getEnname())){
							a.setRoleName("签约人");
						}else if("sqr".equals(role.getEnname())){
							a.setRoleName("申请人");
                            a.setAssigneeName(UserUtils.get(lists.get(lists.size() - 1).getCreateBy().getId()).getName());
						}else {
							if (role.getEnname().contains(buffer)){
								SysRoleActivity r = systemService.getRoleActivityByEnname(role.getEnname());
								a.setRoleName(r.getName());
							}else {
								//如果流程中指定的角色为董事长dsz，而该公司下没有这样角色，则r=null，空指针
								SysRoleActivity r = systemService.getRoleActivityByEnname(buffer+role.getEnname());
								a.setRoleName(r!=null?r.getName():"");
							}
						}
						a.setTaskName(activityProcess.getActivity().getName());
					}

					a.setComment(activityProcess.getRemarks());
					if (i==0){
						a.setBeginDate(endDate);
					}
					histoicFlows.add(a);
				}
			}
			model.addAttribute("histoicFlowList", histoicFlows);
		}
		return "modules/act/actTaskHistoricFlow";
	}

	/**
	 * 获取流程流向图
	 * @param act 流程实例
	 * @param startAct 开始活动节点名称
	 * @param endAct 结束活动节点名称
	 */
	@RequestMapping(value = "flowChart")
	public String flowChart(Act act, String startAct, String endAct, Model model){
		if (StringUtils.isNotBlank(act.getProcInsId())){
			WorkActivityProcess workActivityProcess = new WorkActivityProcess();
			workActivityProcess.setProcessInstanceId(act.getProcInsId());
			/*List<Act> histoicFlows = new ArrayList<>();
			List<Act> histoicFlowList = actTaskService.histoicFlowList(act.getProcInsId(), startAct, endAct);
			histoicFlows = getList(histoicFlowList);*/
			List<WorkActivityProcess> list = workActivityProcessService.findByProcInsId(workActivityProcess);
			workActivityProcess.setIsApproval("0");
			List<WorkActivityProcess> lists = workActivityProcessService.findByProcInsId(workActivityProcess);
			List<Act> histoicFlows = new ArrayList<>();
			if (lists!=null && lists.size()!=0){
				if (list!=null && list.size()!=0){
					WorkActivityProcess activityProcess = list.get(list.size()-1);
					Act a = new Act();
					if (activityProcess.getActivity() ==null){
						a.setTaskName("重申|撤销");
					}else if (activityProcess.getActivity().getUser()!=null && StringUtils.isNotBlank(activityProcess.getActivity().getUser().getId())){
						a.setTaskName(activityProcess.getActivity().getName());
					}else{
						a.setTaskName(activityProcess.getActivity().getName());
					}
					a.setComment(activityProcess.getRemarks());
					histoicFlows.add(a);
				}else {
					Act act1 = new Act();
					act1.setTaskName("开始");
					histoicFlows.add(act1);
				}
				if (lists.size()==1){
					WorkActivityProcess activityProcess = lists.get(0);
					Act a = new Act();
					if (activityProcess.getActivity() ==null) {
						a.setTaskName("重申|撤销");
					}else if (activityProcess.getActivity().getUser()!=null && StringUtils.isNotBlank(activityProcess.getActivity().getUser().getId())){
						a.setTaskName(activityProcess.getActivity().getName());
					}else{
						a.setTaskName(activityProcess.getActivity().getName());
					}
					histoicFlows.add(a);
					Act act1 = new Act();
					act1.setTaskName("结束");
					histoicFlows.add(act1);
				}else {
					for (int i = 0; i < 2; i++) {
						WorkActivityProcess activityProcess = lists.get(i);
						Act a = new Act();
						if (activityProcess.getActivity() == null) {
							a.setTaskName("重申|撤销");
						} else if (activityProcess.getActivity().getUser() != null && StringUtils.isNotBlank(activityProcess.getActivity().getUser().getId())) {
							a.setTaskName(activityProcess.getActivity().getName());
						} else {
							a.setTaskName(activityProcess.getActivity().getName());
						}
						histoicFlows.add(a);
					}
				}
			}else {
				if (list!=null && list.size()>2){
					for (int i = list.size()-2;i<list.size();i++){
						WorkActivityProcess activityProcess = list.get(i);
						Act a = new Act();
						if (activityProcess.getActivity() ==null){
							a.setTaskName("重申|撤销");
						}else if (activityProcess.getActivity().getUser()!=null && StringUtils.isNotBlank(activityProcess.getActivity().getUser().getId())){
							a.setTaskName(activityProcess.getActivity().getName());
						}else{
							a.setTaskName(activityProcess.getActivity().getName());
						}
						a.setComment(activityProcess.getRemarks());
						histoicFlows.add(a);
					}
					Act act2 = new Act();
					act2.setTaskName("结束");
					histoicFlows.add(act2);
				}else if (list!=null && list.size()==1){
					Act act1 = new Act();
					act1.setTaskName("开始");
					histoicFlows.add(act1);
					WorkActivityProcess activityProcess = list.get(list.size()-1);
					Act a = new Act();
					if (activityProcess.getActivity() ==null){
						a.setTaskName("重申|撤销");
					}else if (activityProcess.getActivity().getUser()!=null && StringUtils.isNotBlank(activityProcess.getActivity().getUser().getId())){
						a.setTaskName(activityProcess.getActivity().getName());
					}else{
						a.setTaskName(activityProcess.getActivity().getName());
					}
					a.setComment(activityProcess.getRemarks());
					histoicFlows.add(a);
					Act act2 = new Act();
					act2.setTaskName("结束");
					histoicFlows.add(act2);
				}
			}
			model.addAttribute("histoicFlowList", histoicFlows);
		}
		return "modules/act/actTaskFlowChart";
	}

	public List getList(List<Act> list){
		try {
			List<Act> histoicFlows = new ArrayList<Act>();
			if (list != null && list.size() == 2) {
				if (list.get(1).getEndDate() == null) {
					histoicFlows.add(list.get(1));
					histoicFlows.add(list.get(0));
				} else {
					histoicFlows.addAll(list);
				}
			} else {
				histoicFlows.addAll(list);
			}
			return histoicFlows;
		}catch (Exception e){
			return list;
		}

	}


	/**
	 * 获取流程列表
	 * @param category 流程分类
	 */
	@RequestMapping(value = "process")
	public String processList(String category, HttpServletRequest request, HttpServletResponse response, Model model) {
		Page<Object[]> page = new Page<Object[]>(request, response);
		page = actTaskService.processList(page, category);
		model.addAttribute("page", page);
		model.addAttribute("category", category);
		return "modules/act/actTaskProcessList";
	}

	/**
	 * 获取流程表单
	 * @param act	任务ID
	 */
	@RequestMapping(value = "form")
	public String form(Act act, HttpServletRequest request, Model model){
		// 获取流程XML上的表单KEY
		System.out.println("act"+"-------------"+act.toString());
		String formKey = actTaskService.getFormKey(act.getProcDefId(), act.getTaskDefKey());
		// 获取流程实例对象
		if (act.getProcInsId() != null){
			if(actTaskService.getProcIns(act.getProcInsId())!=null){
				act.setProcIns(actTaskService.getProcIns(act.getProcInsId()));
			}else{
				act.setFinishedProcIns(actTaskService.getFinishedProcIns(act.getProcInsId()));
			}

		}
		return "redirect:" + ActUtils.getFormUrl(formKey, act);

		// 传递参数到视图
//		String formUrl = ActUtils.getFormUrl(formKey, act);
//		model.addAttribute("act", act);
//		model.addAttribute("formUrl", formUrl);
//		return "modules/act/actTaskForm";
	}

	/**
	 * 启动流程
	 * @param act 流程定义KEY
	 * @param table 业务表表名
	 * @param id	业务表编号
	 */
	@RequestMapping(value = "start")
	@ResponseBody
	public String start(Act act, String table, String id, Model model) throws Exception {
		actTaskService.startProcess(act.getProcDefKey(), act.getBusinessId(), act.getBusinessTable(), act.getTitle());
		return "true";//adminPath + "/act/task";
	}

	/**
	 * 签收任务
	 * @param act 任务ID
	 */
	@RequestMapping(value = "claim")
	@ResponseBody
	public String claim(Act act) {
		String userId = UserUtils.getUser().getId();//ObjectUtils.toString(UserUtils.getUser().getId());
		actTaskService.claim(act.getTaskId(), userId);
		return "true";//adminPath + "/act/task";
	}

	/**
	 * 完成任务
	 * @param act 任务ID
	 * 		vars.keys=flag,pass
	 * 		vars.values=1,true
	 * 		vars.types=S,B  @see com.jeeplus.jeeplus.modules.act.utils.PropertyType
	 */
	@RequestMapping(value = "complete")
	@ResponseBody
	public String complete(Act act) {
		actTaskService.complete(act.getTaskId(), act.getProcInsId(), act.getComment(), act.getVars().getVariableMap());
		return "true";//adminPath + "/act/task";
	}

	/**
	 * 读取带跟踪的图片
	 */
	@RequestMapping(value = "trace/photo/{procDefId}/{execId}")
	public void tracePhoto(@PathVariable("procDefId") String procDefId, @PathVariable("execId") String execId, HttpServletResponse response) throws Exception {
		InputStream imageStream = actTaskService.tracePhoto(procDefId, execId);

		// 输出资源内容到相应对象
		byte[] b = new byte[1024];
		int len;
		while ((len = imageStream.read(b, 0, 1024)) != -1) {
			response.getOutputStream().write(b, 0, len);
		}
	}

	/**
	 * 输出跟踪流程信息
	 *
	 * @param proInsId
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping(value = "trace/info/{proInsId}")
	public List<Map<String, Object>> traceInfo(@PathVariable("proInsId") String proInsId) throws Exception {
		List<Map<String, Object>> activityInfos = actTaskService.traceProcess(proInsId);
		return activityInfos;
	}

	/**
	 * 显示流程图

	 @RequestMapping(value = "processPic")
	 public void processPic(String procDefId, HttpServletResponse response) throws Exception {
	 ProcessDefinition procDef = repositoryService.createProcessDefinitionQuery().processDefinitionId(procDefId).singleResult();
	 String diagramResourceName = procDef.getDiagramResourceName();
	 InputStream imageStream = repositoryService.getResourceAsStream(procDef.getDeploymentId(), diagramResourceName);
	 byte[] b = new byte[1024];
	 int len = -1;
	 while ((len = imageStream.read(b, 0, 1024)) != -1) {
	 response.getOutputStream().write(b, 0, len);
	 }
	 }*/

	/**
	 * 获取跟踪信息

	 @RequestMapping(value = "processMap")
	 public String processMap(String procDefId, String proInstId, Model model)
	 throws Exception {
	 List<ActivityImpl> actImpls = new ArrayList<ActivityImpl>();
	 ProcessDefinition processDefinition = repositoryService
	 .createProcessDefinitionQuery().processDefinitionId(procDefId)
	 .singleResult();
	 ProcessDefinitionImpl pdImpl = (ProcessDefinitionImpl) processDefinition;
	 String processDefinitionId = pdImpl.getId();// 流程标识
	 ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
	 .getDeployedProcessDefinition(processDefinitionId);
	 List<ActivityImpl> activitiList = def.getActivities();// 获得当前任务的所有节点
	 List<String> activeActivityIds = runtimeService.getActiveActivityIds(proInstId);
	 for (String activeId : activeActivityIds) {
	 for (ActivityImpl activityImpl : activitiList) {
	 String id = activityImpl.getId();
	 if (activityImpl.isScope()) {
	 if (activityImpl.getActivities().size() > 1) {
	 List<ActivityImpl> subAcList = activityImpl
	 .getActivities();
	 for (ActivityImpl subActImpl : subAcList) {
	 String subid = subActImpl.getId();
	 System.out.println("subImpl:" + subid);
	 if (activeId.equals(subid)) {// 获得执行到那个节点
	 actImpls.add(subActImpl);
	 break;
	 }
	 }
	 }
	 }
	 if (activeId.equals(id)) {// 获得执行到那个节点
	 actImpls.add(activityImpl);
	 System.out.println(id);
	 }
	 }
	 }
	 model.addAttribute("procDefId", procDefId);
	 model.addAttribute("proInstId", proInstId);
	 model.addAttribute("actImpls", actImpls);
	 return "modules/act/actTaskMap";
	 }*/

	/**
	 * 删除任务
	 * @param taskId 流程实例ID
	 * @param reason 删除原因
	 */
	@RequiresPermissions("act:process:edit")
	@RequestMapping(value = "deleteTask")
	public String deleteTask(String taskId, String reason, RedirectAttributes redirectAttributes) {
		if (StringUtils.isBlank(reason)){
			addMessage(redirectAttributes, "请填写删除原因");
		}else{
			actTaskService.deleteTask(taskId, reason);
			addMessage(redirectAttributes, "删除任务成功，任务ID=" + taskId);
		}
		return "redirect:" + adminPath + "/act/task";
	}

	public int compareDate(Date d1,Date d2){
		if (d1.getTime() > d2.getTime()) {
			return 1;
		} else if (d1.getTime() < d2.getTime()) {
			return -1;
		} else {//相等
			return 0;
		}
	}
}
