package cn.myapps.runtime.flowcenter.controller;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import cn.myapps.authtime.domain.model.DomainVO;
import cn.myapps.authtime.domain.service.DomainProcess;
import cn.myapps.common.model.application.Application;
import cn.myapps.runtime.workflow.storage.runtime.ejb.FlowRuntimeService;
import cn.myapps.runtime.workflow.storage.runtime.ejb.FlowRuntimeServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import cn.myapps.authtime.user.model.UserDefined;
import cn.myapps.authtime.user.service.UserDefinedProcess;
import cn.myapps.base.web.WebUser;
import cn.myapps.common.auth.IUser;
import cn.myapps.common.controller.Resource;
import cn.myapps.common.model.resource.StartMenuNode;
import cn.myapps.common.util.StringUtil;
import cn.myapps.runtime.common.controller.AbstractRuntimeController;
import cn.myapps.runtime.flowcenter.service.FlowCenterRumTimeService;
import cn.myapps.util.ProcessFactory;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

/**
 * flowcenter Restful 接口
 * 
 * @author spy
 */
@Api(tags = "流程中心执行模块")
@Component
@RequestMapping(path = "/api/runtime", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class FlowCenterRunTimeController extends AbstractRuntimeController {

	@Autowired
	private FlowCenterRumTimeService flowCenterService;

	/**
	 * 获取发起菜单
	 * 
	 * @param applicationId
	 *            软件id
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/{applicationId}/flowcenters/startmenus")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "获取发起菜单", notes = "获取发起菜单")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
		@ApiImplicitParam(name = "isUsual",value = "是否常用",required = false,paramType = "query",dataType = "boolean"),
		@ApiImplicitParam(name = "isUsualList",value = "是否常用的添加列表",required = false,paramType = "query",dataType = "boolean"),
		@ApiImplicitParam(name = "isMobile",value = "是否移动端",required = false,paramType = "query",dataType = "string")
	})
	public Resource getStartMenus(@PathVariable String applicationId, @RequestParam(required=false) boolean isUsual,  @RequestParam(required=false) boolean isUsualList, @RequestParam(required=false) boolean isMobile)
			throws Exception {
		List<StartMenuNode> result = flowCenterService.getStartMenus(applicationId, isMobile, isUsual, isUsualList, getUser());
		return success("ok", result);
	}

	/**
	 * 获取待办导航
	 * 
	 * @param applicationId
	 *            软件id
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/flowcenters/navs/pendings")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "获取待办导航", notes = "获取待办导航")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "applicationId",value = "软件id",required = false,paramType = "query",dataType = "string")
	})
	public Resource getPendingNavs(@RequestParam(required=false) String applicationId)
			throws Exception {
		List<Map<String, Object>> result = flowCenterService.getPendingNavs(
				applicationId, getUser());
		return success("ok", result);
	}
	

	
	

	/**
	 * 获取经办导航
	 * 
	 * @param applicationId
	 *            软件id
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/flowcenters/navs/processeds")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "获取经办导航", notes = "获取经办导航")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "applicationId",value = "软件id",required = false,paramType = "query",dataType = "string")
	})
	public Resource getProcessedNavs(@RequestParam(required=false) String applicationId)
			throws Exception {
		List<Map<String, Object>> result = flowCenterService.getProcessedNavs(
				applicationId, getUser());
		return success("ok", result);
	}

	/**
	 * 获取抄送导航
	 *
	 * @param applicationId
	 *            软件id
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/flowcenters/navs/carboncopy")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "获取抄送导航", notes = "获取抄送导航")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "applicationId",value = "软件id",required = false,paramType = "query",dataType = "string")
	})
	public Resource getCarboncopyNavs(@RequestParam(required=false) String applicationId,@RequestParam(required=false) boolean isread)
			throws Exception {
		List<Map<String, Object>> result = flowCenterService.getCarboncopyNavs(
				applicationId, getUser(),isread);
		return success("ok", result);
	}

	/**
	 * 获取待办数据
	 * @param applicationId 软件id
	 * @param title 主题内容
	 * @param initiatorId 发起人id 
	 * @param flowId 流程id
	 * @param pageNo 当前页
	 * @param linesPerPage 每页显示条数
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/{applicationId}/flowcenters/pendings")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "获取待办数据", notes = "获取待办数据")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
		@ApiImplicitParam(name = "title",value = "主题内容",required = false,paramType = "query",dataType = "string"),
		@ApiImplicitParam(name = "initiatorId",value = "发起人id",required = false,paramType = "query",dataType = "string"),
		@ApiImplicitParam(name = "flowId",value = "流程id",required = false,paramType = "query",dataType = "string"),
		@ApiImplicitParam(name = "flowname",value = "流程名称",required = false,paramType = "query",dataType = "string"),
		@ApiImplicitParam(name = "pageNo",value = "当前页",required = false,paramType = "query",dataType = "int",defaultValue="1"),
		@ApiImplicitParam(name = "linesPerPage",value = "每页显示条数",required = false,paramType = "query",dataType = "int",defaultValue="5"),
		@ApiImplicitParam(name = "isMobile",value = "是否移动端",required = false,paramType = "query",dataType = "boolean")
	})
	public Resource getPendings(@PathVariable String applicationId,
			@RequestParam(required = false) String title,
			@RequestParam(required = false) String initiatorId,
			@RequestParam(required = false) String flowId,
			@RequestParam(required = false) String flowname,
			@RequestParam(required = false,defaultValue="1") Integer pageNo,
			@RequestParam(required = false,defaultValue="10") Integer linesPerPage,
			@RequestParam(required = false) boolean isMobile)
			throws Exception {
		if(!StringUtil.isBlank(title)){
			title =title.replace("%", "&#37;");
		}
		Map<String, Object> result = flowCenterService.getPendings(
				applicationId, title, flowId, initiatorId,flowname,pageNo, linesPerPage,
				getUser(), isMobile);
		return success("ok", result);
	}

	/**
	 * 标记所有待办为已读
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/flowcenters/pendings/allRead")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "标记所有待办为已读", notes = "标记所有待办为已读")
	@ApiImplicitParams({
	})
	public Resource allRead()
			throws Exception {
		try {
			WebUser user = getUser();
			DomainProcess domainProcess = (DomainProcess) ProcessFactory.createProcess(DomainProcess.class);
			DomainVO domain = (DomainVO) domainProcess.doView(user.getDomainid());
			Collection<Application> bindApplications = domain.getApplications();
			for (Iterator<Application> it = bindApplications.iterator(); it.hasNext(); ) {
				Application vo = it.next();
				FlowRuntimeService flowRuntimeService = new FlowRuntimeServiceImpl(vo.getId());
				flowRuntimeService.allRead(user.getId());
			}
		}catch (Exception e){
			e.printStackTrace();
			return error(500, e.getMessage(), null);
		}
		return success("ok", "success");
	}

	/**
	 * 获取经办数据
	 * @param applicationId 软件id
	 * @param title 主题内容
	 * @param flowId 流程id
	 * @param initiatorId 发起人id
	 * @param isMyWorkFlow 是否我处理
	 * @param status 完成状态
	 * @param pageNo 当前页
	 * @param linesPerPage 每页显示条数
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/{applicationId}/flowcenters/processeds")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "获取经办数据", notes = "获取经办数据")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
		@ApiImplicitParam(name = "title",value = "主题内容",required = false,paramType = "query",dataType = "string"),
		@ApiImplicitParam(name = "flowId",value = "流程id",required = false,paramType = "query",dataType = "string"),
		@ApiImplicitParam(name = "initiatorId",value = "发起人id",required = false,paramType = "query",dataType = "string"),
		@ApiImplicitParam(name = "flowname",value = "流程名称",required = false,paramType = "query",dataType = "string"),
		@ApiImplicitParam(name = "isMyWorkFlow",value = "是否我处理",required = false,paramType = "query",dataType = "boolean"),
		@ApiImplicitParam(name = "status",value = "完成状态",required = false,paramType = "query",dataType = "string"),
		@ApiImplicitParam(name = "pageNo",value = "当前页",required = false,paramType = "query",dataType = "int",defaultValue="1"),
		@ApiImplicitParam(name = "linesPerPage",value = "每页显示条数",required = false,paramType = "query",dataType = "int",defaultValue="5")
	})
	public Resource getProcesseds(@PathVariable String applicationId,
			@RequestParam(required = false) String title,
			@RequestParam(required = false) String flowId,
			@RequestParam(required = false) String initiatorId,
			@RequestParam(required = false) String flowname,
			@RequestParam(required = false) boolean isMyWorkFlow,
			@RequestParam(required = false) String status,
			@RequestParam(required = false,defaultValue="1") Integer pageNo,
			@RequestParam(required = false,defaultValue="10") Integer linesPerPage)
			throws Exception {
		if(!StringUtil.isBlank(title)){
			title =title.replace("%", "&#37;");
		}
		Map<String, Object> result = flowCenterService.getProcesseds(
				applicationId, title, flowId, initiatorId, isMyWorkFlow, status,flowname,
				pageNo, linesPerPage, getUser());
		return success("ok", result);
	}

	/**
	 * 获取抄送数据
	 * @param applicationId 软件id
	 * @param title 主题内容
	 * @param flowId 流程id
	 * @param initiatorId 发起人id
	 * @param isMyWorkFlow 是否我处理
	 * @param isRead 是否已读
	 * @param pageNo 当前页
	 * @param linesPerPage 每页显示条数
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/{applicationId}/flowcenters/carboncopy")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "获取抄送数据", notes = "获取抄送数据")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "title",value = "主题内容",required = false,paramType = "query",dataType = "string"),
			@ApiImplicitParam(name = "flowId",value = "流程id",required = false,paramType = "query",dataType = "string"),
			@ApiImplicitParam(name = "initiatorId",value = "发起人id",required = false,paramType = "query",dataType = "string"),
			@ApiImplicitParam(name = "flowname",value = "流程名称",required = false,paramType = "query",dataType = "string"),
			@ApiImplicitParam(name = "isMyWorkFlow",value = "是否我处理",required = false,paramType = "query",dataType = "boolean"),
			@ApiImplicitParam(name = "isRead",value = "是否已读",required = false,paramType = "query",dataType = "boolean"),
			@ApiImplicitParam(name = "pageNo",value = "当前页",required = false,paramType = "query",dataType = "int",defaultValue="1"),
			@ApiImplicitParam(name = "linesPerPage",value = "每页显示条数",required = false,paramType = "query",dataType = "int",defaultValue="5")
	})
	public Resource getCarboncopy(@PathVariable String applicationId,
								  @RequestParam(required = false) String title,
								  @RequestParam(required = false) String flowId,
								  @RequestParam(required = false) String initiatorId,
								  @RequestParam(required = false) String flowname,
								  @RequestParam(required = false) boolean isMyWorkFlow,
								  @RequestParam(required = false) boolean isRead,
								  @RequestParam(required = false,defaultValue="1") Integer pageNo,
								  @RequestParam(required = false,defaultValue="10") Integer linesPerPage)
			throws Exception {
		if(!StringUtil.isBlank(title)){
			title =title.replace("%", "&#37;");
		}
		Map<String, Object> result = flowCenterService.carboncopy(
				applicationId, title, flowId, initiatorId, false,isRead,flowname,
				pageNo, linesPerPage, getUser());
		return success("ok", result);
	}
	
	/**
	 * 添加常用发起菜单
	 * @param applicationId 
	 * 		软件id
	 * @param id 
	 * 		发起菜单id
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/{applicationId}/flowcenters/startMenus/{id}/usual")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "新建常用发起菜单", notes = "新建常用发起菜单")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
		@ApiImplicitParam(name = "id",value = "发起菜单id",required = true,paramType = "path",dataType = "string")
	})
	public Resource createUsualStartMenu(@PathVariable String applicationId, @PathVariable String id) throws Exception {
		IUser user = getUser();
		
		UserDefinedProcess userDefinedProcess = (UserDefinedProcess) ProcessFactory.createProcess(UserDefinedProcess.class);
    	UserDefined userDefined = userDefinedProcess.doFindMyCustomUserDefined(user);
    	
    	if(userDefined != null){
    		String usualStartMenus = userDefined.getUsualStartMenus();
        	if(!StringUtil.isBlank(usualStartMenus)){
        		JSONArray list = JSONArray.parseArray(usualStartMenus);
        		JSONObject json = new JSONObject();
        		json.put("menuId", id);
        		json.put("count", "1");
        		list.add(json);
        		userDefined.setUsualStartMenus(list.toString());
        		userDefinedProcess.doUpdate(userDefined);
        	} else {
        		JSONArray list = new JSONArray();
        		JSONObject json = new JSONObject();
        		json.put("menuId", id);
        		json.put("count", "1");
        		list.add(json);
        		userDefined.setUsualStartMenus(list.toString());
        		userDefinedProcess.doUpdate(userDefined);
        	}
    	} else {
    		userDefined = new UserDefined();
    		userDefined.setApplicationid(applicationId);
    		userDefined.setCreator(user.getName());
    		userDefined.setDefineMode(16);
    		userDefined.setUserId(user.getId());
    		userDefined.setPublished(true);
    		userDefined.setUsedDefined(0);
    		JSONArray list = new JSONArray();
    		JSONObject json = new JSONObject();
    		json.put("menuId", id);
    		json.put("count", "1");
    		list.add(json);
    		userDefined.setUsualStartMenus(list.toString());
    		userDefinedProcess.doCreate(userDefined);
    	}
		
		return success("ok", "成功");
	}
	
	/**
	 * 更新常用发起菜单（点击次数）
	 * @param applicationId 
	 * 		软件id
	 * @param id 
	 * 		发起菜单id
	 * @return
	 * @throws Exception
	 */
	@PutMapping("/{applicationId}/flowcenters/startMenus/{id}/usual")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "更新常用发起菜单", notes = "更新常用发起菜单")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
		@ApiImplicitParam(name = "id",value = "发起菜单id",required = true,paramType = "path",dataType = "string")
	})
	public Resource updateUsualStartMenu(@PathVariable String applicationId, @PathVariable String id) throws Exception {
		IUser user = getUser();
		
		UserDefinedProcess userDefinedProcess = (UserDefinedProcess) ProcessFactory.createProcess(UserDefinedProcess.class);
    	UserDefined userDefined = userDefinedProcess.doFindMyCustomUserDefined(user);
    	
    	if(userDefined != null){
    		String usualStartMenus = userDefined.getUsualStartMenus();
        	if(!StringUtil.isBlank(usualStartMenus)){
        		JSONArray list = JSONArray.parseArray(usualStartMenus);
        		for (@SuppressWarnings("rawtypes") Iterator iterator = list.iterator(); iterator.hasNext();) {
        			JSONObject json = (JSONObject) iterator.next();
        			String menuId = (String) json.get("menuId");
        			String count = (String) json.get("count");
        			int orderNo = Integer.valueOf(count);
        			if(menuId.equals(id)){
        				json.put("count", ++orderNo + "");
        			}

				}
        		userDefined.setUsualStartMenus(list.toString());
        	} else {
				JSONArray list = new JSONArray();
				List<StartMenuNode> result = flowCenterService.getStartMenus(applicationId, true, true, true,
						getUser());
				for (StartMenuNode startMenuNode : result) {
					JSONObject json = new JSONObject();
					json.put("menuId", startMenuNode.getId());
					if(id.equals(startMenuNode.getId())){
						json.put("count", "1");
					} else {
						json.put("count", "0");
					}
					list.add(json);
				}
				userDefined.setUsualStartMenus(list.toString());
			}
        	userDefinedProcess.doUpdate(userDefined);
    	} else {
			userDefined = new UserDefined();
			userDefined.setApplicationid(applicationId);
			userDefined.setCreator(user.getName());
			userDefined.setDefineMode(16);
			userDefined.setUserId(user.getId());
			userDefined.setPublished(true);
			userDefined.setUsedDefined(0);
			JSONArray list = new JSONArray();

			List<StartMenuNode> result = flowCenterService.getStartMenus(applicationId, true, true, true,
					getUser());
			for (StartMenuNode startMenuNode : result) {
				JSONObject json = new JSONObject();
				json.put("menuId", startMenuNode.getId());
				if(id.equals(startMenuNode.getId())){
					json.put("count", "1");
				} else {
					json.put("count", "0");
				}
				list.add(json);
			}

			userDefined.setUsualStartMenus(list.toString());
			userDefinedProcess.doCreate(userDefined);
		}
		
		return success("ok", "成功");
	}
	
	/**
	 * 移除常用发起菜单
	 * @param applicationId 
	 * 		软件id
	 * @param id 
	 * 		发起菜单id
	 * @return
	 * @throws Exception
	 */
	@DeleteMapping("/{applicationId}/flowcenters/startMenus/{id}/usual")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "删除常用发起菜单", notes = "删除常用发起菜单")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
		@ApiImplicitParam(name = "id",value = "发起菜单id",required = true,paramType = "path",dataType = "string")
	})
	public Resource removeUsualStartMenuTimes(@PathVariable String applicationId, @PathVariable String id) throws Exception {
		IUser user = getUser();
		
		UserDefinedProcess userDefinedProcess = (UserDefinedProcess) ProcessFactory.createProcess(UserDefinedProcess.class);
    	UserDefined userDefined = userDefinedProcess.doFindMyCustomUserDefined(user);
    	
    	if(userDefined != null){
    		String usualStartMenus = userDefined.getUsualStartMenus();
        	if(!StringUtil.isBlank(usualStartMenus)){
        		JSONArray list = JSONArray.parseArray(usualStartMenus);
        		JSONArray result = new JSONArray();
        		result.addAll(list);
        		for (@SuppressWarnings("rawtypes") Iterator iterator = list.iterator(); iterator.hasNext();) {
        			JSONObject json = (JSONObject) iterator.next();
        			String menuId = (String) json.get("menuId");
        			if(menuId.equals(id)){
        				result.remove(json);
        			}
					
				}
        		userDefined.setUsualStartMenus(result.toString());
        	}
        	userDefinedProcess.doUpdate(userDefined);
    	}
		
		return success("ok", "成功");
	}
	
}
