package com.ssm.controller.system;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;





import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.DataBinder;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
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.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.ssm.common.ExceptionReaper;
import com.ssm.common.ResultBack;
import com.ssm.common.SpringInitConfig;
import com.ssm.model.system.SysMenu;
import com.ssm.model.system.SysRole;
import com.ssm.model.system.SysUser;
import com.ssm.model.validator.SysMenuValidator;
import com.ssm.service.system.SysMenuService;
import com.ssm.service.system.SysRoleService;
import com.ssm.util.PackageBeanUtils;
import com.ssm.util.Util;
import com.ssm.util.page.BeanUtil;
import com.ssm.util.page.PagedResult;
import com.ssm.web.Const;
import com.ssm.web.RoleLimit;

/**
 * <b>类说明：接口
 */
@Controller
@RequestMapping(value = "sysMenu")
public class SysMenuController extends ExceptionReaper{

	@Autowired
	private SysMenuService menuService;
	@Autowired
	private SysRoleService sysRoleService;
	/*
	 * 查询菜单
	 */
	@RoleLimit(pid = "sysMenu", mid = "menuTree")
	@ResponseBody
	@RequestMapping(value = "menuTree")
	public ModelAndView selectMenus(HttpSession session, HttpServletRequest request,
			Model model, @RequestParam(value="currentMenu" , required=false) String currentMenu  ){
		model.addAttribute("currentMenu", currentMenu);
		ModelAndView mv = new ModelAndView("sysmenu/menu_list");
		return mv;
	}
	
	@RequestMapping(value = "initDataTree")
	@RoleLimit(pid = Const.SYSTEM_ROLE_LIMIT_PID, mid = Const.SYSTEM_ROLE_LIMIT_MID)
	public String initDataTree(Model model, HttpServletRequest request){
		SysMenu menu= new SysMenu();
		String menucnname = request.getParameter("menucnname");
		if(StringUtils.isNoneBlank(menucnname)){
			menu.setMenucnname(menucnname);
		}
		List<SysMenu> menuList = menuService.menuTree(menu);
//		for(int i = 0; i < menuList.size(); i++){
//			SysMenu m = menuList.get(i);
//			m.setOrderby(i+"");
//			menuService.updateMenu(m);
//		}
		PagedResult<SysMenu> pagedResult = BeanUtil
				.toPagedResult(menuList);
		model.addAttribute("list", pagedResult);
		return "sysmenu/tree_table";
	}
	
	/*
	 * 增加菜单
	 */
	@Transactional(value="txManager")
	@RoleLimit(pid = Const.SYSTEM_ROLE_LIMIT_PID, mid = Const.SYSTEM_ROLE_LIMIT_MID)
	@RequestMapping(value = "insertMenus", method = RequestMethod.POST)
	public String insertMenus(HttpServletRequest request, @Validated @ModelAttribute("sys") SysMenu sys, BindingResult result,HttpSession session, 
			RedirectAttributes attr, Model model) {
		if(result.hasErrors()==false){	
			SysUser sysUser = Util.getUserSession(request);
			sys.setCreateduserid(sysUser.getUserid());
			sys = compleInsertMenu(sys);
			
			if(org.apache.commons.lang.StringUtils.isNotBlank(sys.getMenuurl())){
				SysMenu m = menuService.selectMenuByUrl(sys.getMenuurl());
				if( m != null) {
					result.addError(new FieldError("sys", "menuurl", "url已存在"));
					
					List<SysMenu> parenpagelist = new ArrayList<SysMenu>();
					List<SysMenu> pagemenus = menuService.selectAllpageMenus();
					if(!pagemenus.isEmpty()){
						for (SysMenu sysMenu : pagemenus) {
							if(sysMenu.getLevel() == 1){
								parenpagelist.add(sysMenu);
							}
						}
						if(!parenpagelist.isEmpty()){
							for (int i = 0; i < parenpagelist.size(); i++) {
								PackageBeanUtils.packageParentlist(parenpagelist.get(i) , pagemenus);
							}
						}
					}
					/**
					 * 选择父菜单树
					 */
					model.addAttribute("parentpageList", parenpagelist);
					model.addAttribute("sys", sys);
					
					return "sysmenu/createMenu";
				}
			}
				
			
			if(sys.getLevel() == 3)
				attr.addAttribute("currentMenu", sys.getParentid());
			if(sys.getLevel() == 4){
				SysMenu pMenu = menuService.selectByMenuId(sys.getParentid());
				attr.addAttribute("currentMenu", pMenu.getParentid());
			}
			menuService.insertMenu(sys);
			reloadRoleAndMenu();
			return "redirect:menuTree";
		}
		return "sysmenu/createMenu";
	}

	/**
	 * insert需要补全的字段
	 * @param menu
	 * @return
	 */
	@RoleLimit(pid = Const.SYSTEM_ROLE_LIMIT_PID, mid = Const.SYSTEM_ROLE_LIMIT_MID)
	private SysMenu compleInsertMenu(SysMenu menu) {
		Date date = new Date();
		menu.setCreateddatetime(date);
		menu.setIsdelete(false);
		if(!menu.getIsenable())
			menu.setIsenable(true);
		else
			menu.setIsenable(false);
		Integer parentid = menu.getParentid();
		if(null == parentid){
			menu.setParentid(-1);
			parentid = -1;
			
			//查询 最大的 序列号
			Integer maxOrder = menuService.selectMaxOrder();
			if(maxOrder == null)
				maxOrder = 0;
			menu.setOrderby(maxOrder.toString());
		} else {
			SysMenu parent = menuService.selectByMenuId(parentid);
			Integer maxOrder = findMaxOrderUnderParent(parent);
			menu.setOrderby(maxOrder.toString());
			//将所有的  orderby >= maxOrder的往下移一格
			menuService.updateOrderBy(maxOrder);
		}
		SysMenu pMenuWithBLOBs= menuService.selectByMenuId(parentid);
		if(null == pMenuWithBLOBs){
			menu.setLevel(1);
		}else{
			menu.setLevel(pMenuWithBLOBs.getLevel()+1);
		}
		
//		Integer count =  menuService.selectCountByParentid(parentid);
//		if(0 == count){
//			menu.setMenuid(pMenuWithBLOBs.getMenuid()*1000 +1);
//		}else{
//			Integer  maxMenuid = menuService.selectMaxmenuIdByParentid(parentid);
//			menu.setMenuid(maxMenuid + 1);
//		}
		
		if(null == menu.getMenutype() || "".equals(menu.getMenutype()))
			menu.setMenutype("Page");
		return menu;
	}
	
	
	/**
	 * 递归查询 父节点下的 最大的序列号
	 * @param parentId
	 */
	@RoleLimit(pid = Const.SYSTEM_ROLE_LIMIT_PID, mid = Const.SYSTEM_ROLE_LIMIT_MID)
	private Integer findMaxOrderUnderParent(SysMenu parent) {
		Integer maxOrderId = menuService.selectMaxOrderIdUnderParent(parent.getMenuid());
		Integer returnOrder = 0;
		if(maxOrderId == null) { //没有菜单节点
			returnOrder = Integer.valueOf(parent.getOrderby())+1;
		} else { //存在子菜单
			//看最大一个 兄弟节点是否有子节点
			List<SysMenu> menuList = sysRoleService.selectChildMenusByPageMenuId(maxOrderId);
			if(!menuList.isEmpty()) {
				SysMenu menu = menuList.get(menuList.size()-1); //最大的子节点
				returnOrder = findMaxOrderUnderParent(menu);
			} else {
				Integer maxOrder = menuService.selectMaxOrderUnderParent(parent.getMenuid());
				returnOrder = maxOrder+1;
			}
		}
		return returnOrder;
	}
	
	
	/**
	 * update  需要补全的字段
	 * @param menu
	 * @return
	 */
	@RoleLimit(pid = Const.SYSTEM_ROLE_LIMIT_PID, mid = Const.SYSTEM_ROLE_LIMIT_MID)
	private SysMenu compleUpdateMenu(SysMenu menu) {
		Date date = new Date();
		menu.setLastupdatedatetime(date);
		if(!menu.getIsenable())
			menu.setIsenable(true);
		else
			menu.setIsenable(false);
		return menu;
	}

	/*
	 * 修改菜单
	 */
	@Transactional(value="txManager")
	@RoleLimit(pid = Const.SYSTEM_ROLE_LIMIT_PID, mid = Const.SYSTEM_ROLE_LIMIT_MID)
	@RequestMapping(value = "updateMenus", method = RequestMethod.POST)
	public String updateMenus(@Validated @ModelAttribute("sys") SysMenu sys, 
			BindingResult result, HttpSession session, Model model, HttpServletRequest request, RedirectAttributes attr) {
		SysMenu old = menuService.selectByMenuId(sys.getMenuid());
		if(result.hasErrors()==false){
			SysUser sysUser = Util.getUserSession(request);
			try {
				sys.setLastupdateuserid(sysUser.getUserid());
				sys = compleUpdateMenu(sys);
				if(org.apache.commons.lang.StringUtils.isNotBlank(sys.getMenuurl())){
					SysMenu m = null;
					if(!old.getMenuurl().equalsIgnoreCase(sys.getMenuurl())) {
						m = menuService.selectMenuByUrl(sys.getMenuurl());
					}
					if( m != null) {
						result.addError(new FieldError("sys", "menuurl", "url已存在"));
						List<SysMenu> parenpagelist = new ArrayList<SysMenu>();
						List<SysMenu> pagemenus = menuService.selectAllpageMenus();
						if(null != pagemenus && pagemenus.size() > 0){
							for (SysMenu sysMenu : pagemenus) {
								if(sysMenu.getLevel() == 1){
									parenpagelist.add(sysMenu);
								}
								
							}
							if(null != parenpagelist && parenpagelist.size() > 0){
								for (int i = 0; i < parenpagelist.size(); i++) {
									PackageBeanUtils.packageParentlist( parenpagelist.get(i) , pagemenus);
								}
							}
						}
						model.addAttribute("parentpageList", parenpagelist);
						model.addAttribute("editmenu", sys);
						return "sysmenu/editMenu";
					}
				}
				menuService.updateMenu(sys);
			} catch (Exception e) {
				result.addError(new FieldError("res", "errmsg", "修改失败，请检查后再提交"));
				return toBack(model);
			}
//			menuService.renewalMenuSession(session, sysUser);
			SysMenu menu = menuService.selectByMenuId(sys.getMenuid());
			if(menu.getLevel() == 3)
				attr.addAttribute("currentMenu", menu.getParentid());
			if(menu.getLevel() == 4){
				SysMenu pMenu = menuService.selectByMenuId(menu.getParentid());
				attr.addAttribute("currentMenu", pMenu.getParentid());
			}
			reloadRoleAndMenu();
			return "redirect:menuTree";
		}
		return "sysmenu/editMenu";

	}
	/**
	 * 跳转到菜单修改页面
	 * @param request
	 * @param session
	 * @return
	 */
	@RoleLimit(pid = Const.SYSTEM_ROLE_LIMIT_PID, mid = Const.SYSTEM_ROLE_LIMIT_MID)
	@RequestMapping(value = "editMenu")
	public ModelAndView editMenu(HttpServletRequest request,HttpSession session) {
		ModelAndView mv = new ModelAndView("sysmenu/editMenu");
		SysMenu sysMenuWithBLOBs  = new SysMenu();
		List<SysMenu> parenpagelist = new ArrayList<SysMenu>();
		String id = request.getParameter("id");
		if(StringUtils.isNoneBlank(id)){
			
			sysMenuWithBLOBs = menuService.selectByPrimaryKey(Integer.valueOf(id));
			
		}
		
		List<SysMenu> pagemenus = menuService.selectAllpageMenus();
		if(null != pagemenus && pagemenus.size() > 0){
			for (SysMenu sysMenu : pagemenus) {
				
				if(sysMenu.getLevel() == 1){
					parenpagelist.add(sysMenu);
					
				}
				
			}
			if(null != parenpagelist && parenpagelist.size() > 0){
				
				for (int i = 0; i < parenpagelist.size(); i++) {
					
					PackageBeanUtils.packageParentlist( parenpagelist.get(i) , pagemenus);
				}
			}
		}
		mv.addObject("editmenu", sysMenuWithBLOBs);
		/**
		 * 选择父菜单树
		 */
		mv.addObject("parentpageList", parenpagelist);
		mv.addObject("sys", new SysMenu());
		return mv;
	}

	/**
	 * 跳转到新增页面
	 * @param request
	 * @param session
	 * @return
	 */
	@RoleLimit(pid = "sysMenu", mid = "createMenu")
	@RequestMapping(value = "createMenu")
	public ModelAndView createMenu(HttpServletRequest request,HttpSession session) {
		ModelAndView mv = new ModelAndView("sysmenu/createMenu");
		List<SysMenu> parenpagelist = new ArrayList<SysMenu>();
		List<SysMenu> pagemenus = menuService.selectAllpageMenus();
		
		if(!pagemenus.isEmpty()){
			for (SysMenu sysMenu : pagemenus) {
				
				if(sysMenu.getLevel() == 1){
					parenpagelist.add(sysMenu);
					
				}
				
			}
			if(!parenpagelist.isEmpty()){
				
				for (int i = 0; i < parenpagelist.size(); i++) {
					
					PackageBeanUtils.packageParentlist(parenpagelist.get(i) , pagemenus);
				}
			}
			
//			if(!parenpagelist.isEmpty()){
//				for(SysMenu first : parenpagelist) {
//					System.out.println("first ====>"+first.getMenucnname());
//					for(SysMenu second : first.getChildMenu()){
//						System.out.println("second ====>"+second.getMenucnname());
//						for(SysMenu third : second.getChildMenu()){
//							System.out.println("third ====>"+third.getMenucnname());
//						}
//					}
//				}
//			}
			
		}
		/**
		 * 选择父菜单树
		 */
		mv.addObject("parentpageList", parenpagelist);
		mv.addObject("sys", new SysMenu());
		return mv;
	}
	
	/**
	 * 校验角色新增
	 * @param binder
	 */
	@InitBinder("sys")
	@RoleLimit(pid = Const.SYSTEM_ROLE_LIMIT_PID, mid = Const.SYSTEM_ROLE_LIMIT_MID)
	public void InitBinder(DataBinder binder){
		binder.setValidator(new SysMenuValidator());
	}

	/*
	 * 删除菜单
	 */
	@ResponseBody
	@Transactional(value="txManager")
	@RoleLimit(pid = "sysMenu", mid = "deleteMenu")
	@RequestMapping(value = "deleteMenu", method = RequestMethod.POST)
	public Map<String, Object> deleteMenus(HttpServletRequest request, HttpSession session) {
		Map<String, Object> record = new HashMap<String, Object>();
		record.put("success", true);
		String menuid = "";
		SysUser sysUser = Util.getUserSession(request);
		try {
			menuid = request.getParameter("menuid");
			//先查询是否有子节点,若有,则不允许删除
			int count = menuService.countSonMenu(Integer.valueOf(menuid));
			if(count > 0) {
				record.put("success", false);
				record.put("info", "请先删除子菜单");
			} else {
				menuService.deleteMenuById(menuid, sysUser.getUserid());
			}
		} catch (Exception e) {
			record.put("success", false);
		}
		reloadRoleAndMenu();
		return record;
	}
	
	/*
	 * 删除菜单
	 */
	@RoleLimit(pid = Const.SYSTEM_ROLE_LIMIT_PID, mid = Const.SYSTEM_ROLE_LIMIT_MID)
	@Transactional(value="txManager")
	@RequestMapping(value = "freezeMenus", method = RequestMethod.POST)
	public Map<String, Object> freezeMenus(HttpServletRequest request, @RequestParam("menuId") Integer menuId, HttpSession session) {
		
		SysUser sysUser = Util.getUserSession(request);
		Map<String, Object> record = new HashMap<String, Object>();
		record.put("success", true);
		
		SysMenu menu = menuService.selectByPrimaryKey(menuId);
		if(menu != null ) {
			Boolean isenable = !menu.getIsenable();
			menu.setIsenable(isenable);
			menu.setLastupdateuserid(sysUser.getUserid());
			menu.setLastupdatedatetime(new Date());
			Integer count  = menuService.freezeMenuById(menu);
			if(count <= 0)
				record.put("success", false);
			
			record.put("menuStatus", isenable);
		} else {
			record.put("success", false);
		}
		reloadRoleAndMenu();
		return record;
	}
	
	
	@RoleLimit(pid = Const.SYSTEM_ROLE_LIMIT_PID, mid = Const.SYSTEM_ROLE_LIMIT_MID)
	//@RequestMapping(value="login", method=RequestMethod.GET)
	public String toBack(Model model) {
		if(!model.containsAttribute("res"))
			model.addAttribute("res", new ResultBack());
		return "editMenu";
	}
	
	
	/**
	 * 当用户 超级管理员 修改 菜单时, 需要 同步 到map中
	 */
	@RoleLimit(pid = Const.SYSTEM_ROLE_LIMIT_PID, mid = Const.SYSTEM_ROLE_LIMIT_MID)
	public void reloadRoleAndMenu(){
		//清空所有的菜单和角色
		Iterator<Entry<String, List<SysMenu>>> it = SpringInitConfig.menuMap.entrySet().iterator();  
        while(it.hasNext()){  
           it.next();  
           it.remove();
        }  
        
        List<SysRole> roleList = sysRoleService.selectRoleAndMenuList();
		if( !roleList.isEmpty() ) {
			for(SysRole role : roleList) {
				SpringInitConfig.roleMap.put(role.getRoleId().toString(), role);
				SpringInitConfig.menuMap.put(role.getRoleId().toString(), role.getMenuList());
			}
			
		}
		//下面代码 可以 注释
		for(String key : SpringInitConfig.menuMap.keySet() ){
			System.out.println( "==================================================" );
			SysRole role = SpringInitConfig.roleMap.get(key);
			System.out.print( "角色 :"+ role.getRoleName()  +" 菜单>>>");
			List<SysMenu> menuList = SpringInitConfig.menuMap.get(key);
			if(!menuList.isEmpty()) {
				for(SysMenu menu : menuList) {
					System.out.println(  menu.getMenucnname() );
				}
			}
		}
        
	}
	
	
	/**
	 * 菜单节点上移
	 * @return
	 */
	@Transactional(value="txManager")
	@RoleLimit(pid = Const.SYSTEM_ROLE_LIMIT_PID, mid = Const.SYSTEM_ROLE_LIMIT_MID)
	@RequestMapping(value="moveUp", method = RequestMethod.POST)
	public String moveUp(@RequestParam("menuId") Integer menuId, HttpSession session, Model model){
		//要移动的节点
		SysMenu from = menuService.selectByPrimaryKey(menuId);
		Integer orderBy = menuService.selectPrevOrder(from.getLevel(), Integer.valueOf(from.getOrderby()), from.getParentid());
		SysMenu to = menuService.selectMenuByOrderAndParent(orderBy, from.getParentid());
		
		List<SysMenu> addList = new ArrayList<SysMenu>();
		List<SysMenu> delList = new ArrayList<SysMenu>();
		Integer nextOrder = menuService.selectNextOrder(from.getLevel(), Integer.valueOf(from.getOrderby()), from.getParentid());
		if(nextOrder == null) {
			if(from.getParentid() == -1) {
				Integer maxOrder = menuService.selectMaxOrder();
				delList = menuService.deleteOrderBy(Integer.valueOf(from.getOrderby()), maxOrder);
			} else {
				nextOrder = menuService.selectNextLevel(from.getLevel()-1, Integer.valueOf(from.getOrderby()));
				if(nextOrder == null) {
					Integer maxOrder = menuService.selectMaxOrder();
					delList = menuService.deleteOrderBy(Integer.valueOf(from.getOrderby()), maxOrder);
				} else {
					delList = menuService.deleteOrderBy(Integer.valueOf(from.getOrderby()), nextOrder);
				}
			}
		} else {
			delList = menuService.deleteOrderBy(Integer.valueOf(from.getOrderby()), nextOrder);
		}
		
		addList = menuService.addOrderBy(Integer.valueOf(to.getOrderby()), Integer.valueOf(from.getOrderby()));
		String orderFrom = delList.get(delList.size()-1).getOrderby();
		String orderTo = addList.get(0).getOrderby();
		int count  = Integer.valueOf(orderFrom) - Integer.valueOf(orderTo) +1; 
		
		//1.序列比orderFrom大的全部加上  count
		//2.addList 全部加上 count ,则节点移动成功
		menuService.updateOrderByCount(count, Integer.valueOf(orderFrom));
		
		for(SysMenu menu : addList) {
			Integer newOrder = Integer.valueOf(menu.getOrderby()) + count;
			menu.setOrderby(newOrder.toString());
			menuService.updateMenu(menu);
		}
		
		//回显到页面
		List<SysMenu> menuList = menuService.menuTree(new SysMenu());
		PagedResult<SysMenu> pagedResult = BeanUtil
				.toPagedResult(menuList);
		model.addAttribute("list", pagedResult);
		reloadRoleAndMenu();
		return "sysmenu/tree_table";
	}
	
}
