package com.blueland.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.blueland.constant.RedisConstant;
import com.blueland.core.util.StringUtil;
import com.blueland.bo.*;
import com.blueland.dao.MenuDao;
import com.blueland.model.TPfMenu;
import com.blueland.service.IAuthService;
import com.blueland.service.IMenuService;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Service
public class MenuServiceImpl extends ServiceImpl<MenuDao, TPfMenu> implements IMenuService {

	@Autowired
	private MenuDao menuDao;
	@Autowired
	private IAuthService authService;

	@Override
	public List<MenuEntity> findAppIdMenuList(String appId) {
		return this.menuList(appId, "");
	}

	private List<MenuEntity> menuList(String appId, String parentId) {
		List<MenuEntity> topMenuList = menuDao.findAppIdMenuList(appId, parentId);
		if (topMenuList.isEmpty()) {
			return topMenuList;
		}
		for (MenuEntity entity : topMenuList) {
			List<MenuEntity> list = this.menuList(appId, entity.getMenuId());
			entity.setChildren(list);
		}
		return topMenuList;
	}

	/**
	 * 根据应用ID、员工ID查询有权限访问的菜单列表
	 * @param appId
	 * @param userId
	 * @param menuType
	 * @param
	 * @param
	 * @param menuId
	 * @return
	 */
	@Override
	public List<MenuEntity> getMenu(String appId, String userId, String menuType, String menuId) {
		// TODO Auto-generated method stub
		List<MenuEntity> returnDatas = menuDao.getMenu(appId, userId, menuType, menuId);
		return returnDatas;
	}

	/**
	 * 获得应用下为启用的权限
	 * @param appId
	 * @return
	 */
	@Override
	public List<MenuEntity> getMenuIsOpenStatus(String appId) {
		List<MenuEntity> returnDatas = menuDao.getMenuIsOpenStatus(appId);
		return returnDatas;
	}
	
	/**
	 * 获取一级菜单
	 * @param appId
	 * @param menuName
	 * @param parentName
	 * @param menuType
	 * @return
	 */
	@Override
	public List<MenuEntity> getMenuList(String appId, String menuName,String parentName, String menuType) {
		List<MenuEntity> resultDate = new  ArrayList<>();
		//根据应用ID获取菜单列表
		List<MenuEntity> resultList = menuDao.getMenuTop(appId, menuName, parentName, menuType);
		for(MenuEntity menuList : resultList) {
			MenuEntity menuEntity = new MenuEntity();
			List<MenuEntity> MenuEntity = menuDao.getParent(menuList.getMenuId(),menuList.getAppId());
			boolean isparent =false;
			
			if(MenuEntity.size()>0) {
				isparent = true;
			}
			menuEntity.setMenuId(menuList.getMenuId());
			menuEntity.setMenuParentId(menuList.getMenuParentId());
			menuEntity.setMenuName(menuList.getMenuName());
			menuEntity.setAppId(menuList.getAppId());
			menuEntity.setIsParent(isparent);
			menuEntity.setHasChildren(isparent);
			menuEntity.setMenuType(menuList.getMenuType());
			menuEntity.setCreateDate(menuList.getCreateDate());
			menuEntity.setCreatorId(menuList.getCreatorId());
			menuEntity.setMenuCode(menuList.getMenuCode());
			menuEntity.setMenuIcon(menuList.getMenuIcon());
			menuEntity.setMenuLevel(menuList.getMenuLevel());
			menuEntity.setMenuUrl(menuList.getMenuUrl());
			menuEntity.setOpenStatus(menuList.getOpenStatus());
			menuEntity.setOpenType(menuList.getOpenType());
			menuEntity.setRemark(menuList.getRemark());
			menuEntity.setSort(menuList.getSort());
			menuEntity.setStatus(menuList.getStatus());
			menuEntity.setUpdateDate(menuList.getUpdateDate());
			menuEntity.setUpdatorId(menuList.getUpdatorId());
			resultDate.add(menuEntity);
		}
		return resultDate;
	}

	@Override
	public List<MenuEntity> getMenuChildren(String appId, String menuName,String parentName, String menuType) {
//		List<MenuEntity> result = menuDao.getMenuAll(appId, menuName,parentName,menuType);
		List<MenuEntity> resultDate = new  ArrayList();
		List<MenuEntity> resultDateList = new  ArrayList();
//		List<MenuEntity> topList = menuDao.getMenuTop(appId, menuName,parentName,menuType);
//		List<MenuEntity> resultList = menuDao.getMenuNoTop(appId, menuName,parentName,menuType);
		
		List<MenuEntity> resultList = menuDao.getMenuTop(appId, menuName, parentName, menuType);
		for(MenuEntity menuList : resultList) {
			MenuEntity menuEntity = new MenuEntity();
			List<MenuEntity> menuentity = menuDao.getParent(menuList.getMenuId(),menuList.getAppId());
			boolean isparent =false;
			
			if(menuentity.size()>0) {
				isparent = true;
				getChild(menuEntity, menuentity);
			}
			menuEntity.setMenuId(menuList.getMenuId());
			menuEntity.setMenuParentId(menuList.getMenuParentId());
			menuEntity.setMenuName(menuList.getMenuName());
			menuEntity.setAppId(menuList.getAppId());
			menuEntity.setIsParent(isparent);
			menuEntity.setHasChildren(isparent);
			menuEntity.setMenuType(menuList.getMenuType());
			menuEntity.setCreateDate(menuList.getCreateDate());
			menuEntity.setCreatorId(menuList.getCreatorId());
			menuEntity.setMenuCode(menuList.getMenuCode());
			menuEntity.setMenuIcon(menuList.getMenuIcon());
			menuEntity.setMenuLevel(menuList.getMenuLevel());
			menuEntity.setMenuUrl(menuList.getMenuUrl());
			menuEntity.setOpenStatus(menuList.getOpenStatus());
			menuEntity.setOpenType(menuList.getOpenType());
			menuEntity.setRemark(menuList.getRemark());
			menuEntity.setSort(menuList.getSort());
			menuEntity.setStatus(menuList.getStatus());
			menuEntity.setUpdateDate(menuList.getUpdateDate());
			menuEntity.setUpdatorId(menuList.getUpdatorId());
			//menuEntity.setChildren(resultDateList);
			resultDate.add(menuEntity);
		}
		return resultDate;
	}
	
	
	private void getChild(MenuEntity menuEntity,List<MenuEntity> menuList) {
		menuEntity.setChildren(menuList);
		for(MenuEntity mList : menuList) {
			List<MenuEntity> menuEntityList = menuDao.getParent(mList.getMenuId(),mList.getAppId());
			if(menuEntityList.size()>0) {
				menuEntity.setIsParent(true);
				menuEntity.setHasChildren(true);
				getChild(mList, menuEntityList);
			}else {
				menuEntity.setIsParent(false);
				menuEntity.setHasChildren(false);
			}
			
		}
	}
	
	//20200330 add一个参数authMap ，优化查询速度
	private void getChildRole(MenuEntity menuEntity,List<MenuEntity> menuList,String roleId, Map<String,AuthEntity> authMap) {
		menuEntity.setChildren(menuList);
		for(MenuEntity mList : menuList) {
			List<MenuEntity> menuEntityList = menuDao.getParent(mList.getMenuId(),mList.getAppId());
			List<MenuEntity> menuEntityList_new = new ArrayList<>();
			for(MenuEntity mList3:menuEntityList) {
//				int flag2 = authService.findAuthByMenuIdRoleId(mList3.getMenuId(), roleId);
//				if(flag2 > 0) {
//					menuEntityList_new.add(mList3);
//				}
				// 20200330 modify TASK584 优化系统管理编辑角色的时候 权限查询速度
				if(authMap.containsKey(mList3.getMenuId())) {
					menuEntityList_new.add(mList3);
				}
			}
			if(menuEntityList_new.size()>0) {
				menuEntity.setIsParent(true);
				getChildRole(mList, menuEntityList_new, roleId, authMap);
			}else {
				menuEntity.setIsParent(false);
			}
		}
	}
	
	@Override
	public List<MenuEntity> getMenuAll(String appId, String menuName,String parentName, String menuType) {
		List<MenuEntity> result = menuDao.getMenuAll(appId, menuName,parentName,menuType);
		return result;
	}

	@Override
	public List<MenuEntity> getParent(String menuId,String appId) {
		// TODO Auto-generated method stub
		List<MenuEntity> resultDate = new  ArrayList();
		List<MenuEntity> result = menuDao.getParent(menuId,appId);
		
		for(MenuEntity menuList : result) {
			MenuEntity menuEntity = new MenuEntity();
			List<MenuEntity> MenuEntity = menuDao.getParent(menuList.getMenuId(),menuList.getAppId());
			boolean isparent =false;
			if(MenuEntity.size()>0) {
				isparent = true;
			}
			menuEntity.setMenuId(menuList.getMenuId());
			menuEntity.setMenuParentId(menuList.getMenuParentId());
			menuEntity.setMenuName(menuList.getMenuName());
			menuEntity.setAppId(menuList.getAppId());
			menuEntity.setIsParent(isparent);
			menuEntity.setHasChildren(isparent);
			menuEntity.setMenuType(menuList.getMenuType());
			menuEntity.setCreateDate(menuList.getCreateDate());
			menuEntity.setCreatorId(menuList.getCreatorId());
			menuEntity.setMenuCode(menuList.getMenuCode());
			menuEntity.setMenuIcon(menuList.getMenuIcon());
			menuEntity.setMenuLevel(menuList.getMenuLevel());
			menuEntity.setMenuUrl(menuList.getMenuUrl());
			menuEntity.setOpenStatus(menuList.getOpenStatus());
			menuEntity.setOpenType(menuList.getOpenType());
			menuEntity.setRemark(menuList.getRemark());
			menuEntity.setSort(menuList.getSort());
			menuEntity.setStatus(menuList.getStatus());
			menuEntity.setUpdateDate(menuList.getUpdateDate());
			menuEntity.setUpdatorId(menuList.getUpdatorId());
			resultDate.add(menuEntity);
		}
		return resultDate;
	}

	@Override
	public List<MenuEntity> listRoleMenu(String roleId,String appId) {
		List<MenuEntity> resultDate = new ArrayList<>();
		List<MenuEntity> resultList = menuDao.listRoleMenu(appId);
		if(StringUtils.isNotBlank(roleId)) {
			// 20200330 modify TASK584 优化系统管理编辑角色的时候 权限查询速度
			Map<String,AuthEntity> authMap = authService.getMapByRoleId(roleId);
			for(MenuEntity mList:resultList ) {
//				int flag0 = authService.findAuthByMenuIdRoleId(mList.getMenuId(), roleId);
//				if(flag0>0 && StringUtils.isNotBlank(roleId)) {
				if(authMap.containsKey(mList.getMenuId())) {
					MenuEntity menuEntity = new MenuEntity();
					List<MenuEntity> menuList = menuDao.getParentRole(mList.getMenuId(),mList.getAppId(),roleId);
					List<MenuEntity> menuList_new = new ArrayList<>();
					for(MenuEntity mList2:menuList) {
//						int flag1 = authService.findAuthByMenuIdRoleId(mList2.getMenuId(), roleId);
//						if(flag1 > 0) {
//							menuList_new.add(mList2);
//						}
						// 20200330 modify TASK584 优化系统管理编辑角色的时候 权限查询速度
						if(authMap.containsKey(mList2.getMenuId())) {
							menuList_new.add(mList2);
						}
					}
					
					boolean isparent =false;
					if(menuList_new.size()>0) {
						isparent = true;
						getChildRole(menuEntity, menuList_new, roleId, authMap);
					}
					menuEntity.setMenuId(mList.getMenuId());
					menuEntity.setMenuParentId(mList.getMenuParentId());
					menuEntity.setMenuName(mList.getMenuName());
					menuEntity.setAppId(mList.getAppId());
					menuEntity.setIsParent(isparent);
					menuEntity.setMenuType(mList.getMenuType());
					menuEntity.setCreateDate(mList.getCreateDate());
					menuEntity.setCreatorId(mList.getCreatorId());
					menuEntity.setMenuCode(mList.getMenuCode());
					menuEntity.setMenuIcon(mList.getMenuIcon());
					menuEntity.setMenuLevel(mList.getMenuLevel());
					menuEntity.setMenuUrl(mList.getMenuUrl());
					menuEntity.setOpenStatus(mList.getOpenStatus());
					menuEntity.setOpenType(mList.getOpenType());
					menuEntity.setRemark(mList.getRemark());
					menuEntity.setSort(mList.getSort());
					menuEntity.setStatus(mList.getStatus());
					menuEntity.setUpdateDate(mList.getUpdateDate());
					menuEntity.setUpdatorId(mList.getUpdatorId());
					resultDate.add(menuEntity);
				}
			}
		}
		return resultDate;
	}

	@Override
	public int getMenuLevel(String menuParentId) {
        return menuDao.getMenuLevel(menuParentId);
	}

	@Override
	public List<MenuEntity> getMenuCode(String menuCode, String userId,String appId,String menuType) {
		// TODO Auto-generated method stub
		List<MenuEntity> list = menuDao.getMenuCode(menuCode,userId,appId,menuType);
		return list;
	}

	@Override
	public Map<String,Object> getButton(String appId,String userId,String menuCode){
		HashMap<String, Object> rs = Maps.newHashMap();
		//有权限操作的按钮
		List<MenuEntity> operationButtonlist = menuDao.getMenuCode(menuCode,userId,appId,"button");
		//当前菜单下所有按钮
		List<MenuEntity> buttonList = menuDao.getButtonByMenuCode(menuCode);
		for (MenuEntity menuEntity:
			 buttonList) {
			rs.put(menuEntity.getMenuCode(),false);
			for (MenuEntity opreationMenuEntity:
					operationButtonlist) {
				if(StringUtil.notEmpty(opreationMenuEntity.getMenuCode()) &&
						StringUtil.notEmpty(menuEntity.getMenuCode()) &&
						opreationMenuEntity.getMenuCode().equals(menuEntity.getMenuCode())
				){
					rs.put(menuEntity.getMenuCode(),true);
					continue;
				}
			}
		}
		return rs;
	}

	@Override
	public List<MenuEntity> getMenuByRoleIdAndAppId(String appId,String roleId){
		return menuDao.getMenuByRoleIdAndAppId(appId, roleId);
	}
	
	/**
	 * 根据staffcode和appid查询改员工的一级菜单、操作权限目录
	 * @param appId
	 * @param staffCode
	 * @return
	 * @author hpp
	 * @Time 2021年5月18日 上午9:45:43
	 */
	@Override
	public List<MenuEntity> getMenuListByStaffcode(String appId, String staffCode) {
		List<MenuEntity> resultDate = new  ArrayList<>();
		//根据应用ID获取菜单列表
		List<MenuEntity> resultList = menuDao.getMenuTopByStaffCode(appId, staffCode);
		for(MenuEntity menuList : resultList) {
			MenuEntity menuEntity = new MenuEntity();
			List<MenuEntity> MenuEntity = menuDao.getParentByStaffCode(menuList.getMenuId(),menuList.getAppId(), staffCode);
			boolean isparent =false;
			if(MenuEntity.size()>0) {
				isparent = true;
			}
			menuEntity.setMenuId(menuList.getMenuId());
			menuEntity.setMenuParentId(menuList.getMenuParentId());
			menuEntity.setMenuName(menuList.getMenuName());
			menuEntity.setAppId(menuList.getAppId());
			menuEntity.setIsParent(isparent);
			menuEntity.setHasChildren(isparent);
			menuEntity.setMenuType(menuList.getMenuType());
			menuEntity.setCreateDate(menuList.getCreateDate());
			menuEntity.setCreatorId(menuList.getCreatorId());
			menuEntity.setMenuCode(menuList.getMenuCode());
			menuEntity.setMenuIcon(menuList.getMenuIcon());
			menuEntity.setMenuLevel(menuList.getMenuLevel());
			menuEntity.setMenuUrl(menuList.getMenuUrl());
			menuEntity.setOpenStatus(menuList.getOpenStatus());
			menuEntity.setOpenType(menuList.getOpenType());
			menuEntity.setRemark(menuList.getRemark());
			menuEntity.setSort(menuList.getSort());
			menuEntity.setStatus(menuList.getStatus());
			menuEntity.setUpdateDate(menuList.getUpdateDate());
			menuEntity.setUpdatorId(menuList.getUpdatorId());
			resultDate.add(menuEntity);
		}
		return resultDate;
	}
	
	/**
	 * 查看该员工所拥有的下家菜单、操作权限
	 * @param menuId
	 * @param appId
	 * @param staffCode
	 * @return
	 * @author hpp
	 * @Time 2021年5月18日 上午10:27:06
	 */
	@Override
	public List<MenuEntity> getParentByStaffcode(String menuId, String appId, String staffCode) {
		List<MenuEntity> resultDate = new  ArrayList<>();
		List<MenuEntity> result = menuDao.getParentByStaffCode(menuId,appId, staffCode);
		for(MenuEntity menuList : result) {
			MenuEntity menuEntity = new MenuEntity();
			List<MenuEntity> MenuEntity = menuDao.getParentByStaffCode(menuList.getMenuId(),menuList.getAppId(), staffCode);
			boolean isparent =false;
			if(MenuEntity.size()>0) {
				isparent = true;
			}
			menuEntity.setMenuId(menuList.getMenuId());
			menuEntity.setMenuParentId(menuList.getMenuParentId());
			menuEntity.setMenuName(menuList.getMenuName());
			menuEntity.setAppId(menuList.getAppId());
			menuEntity.setIsParent(isparent);
			menuEntity.setHasChildren(isparent);
			menuEntity.setMenuType(menuList.getMenuType());
			menuEntity.setCreateDate(menuList.getCreateDate());
			menuEntity.setCreatorId(menuList.getCreatorId());
			menuEntity.setMenuCode(menuList.getMenuCode());
			menuEntity.setMenuIcon(menuList.getMenuIcon());
			menuEntity.setMenuLevel(menuList.getMenuLevel());
			menuEntity.setMenuUrl(menuList.getMenuUrl());
			menuEntity.setOpenStatus(menuList.getOpenStatus());
			menuEntity.setOpenType(menuList.getOpenType());
			menuEntity.setRemark(menuList.getRemark());
			menuEntity.setSort(menuList.getSort());
			menuEntity.setStatus(menuList.getStatus());
			menuEntity.setUpdateDate(menuList.getUpdateDate());
			menuEntity.setUpdatorId(menuList.getUpdatorId());
			resultDate.add(menuEntity);
		}
		return resultDate;
	}

    @Autowired
    private RedisTemplate redisTemplate;

	@Override
	public TPfMenu get(MenuEntity bo) {
		return this.baseMapper.selectOne(buildQueryWrapper(bo));
	}

	@Override
	public Page<MenuEntity> findPage(MenuEntity bo) {
		Page<MenuEntity> page = new Page(bo.getPageNum(), bo.getPageSize());
		return this.baseMapper.findPage(page, bo);
	}

	// 6.0.0

	@Override
	public List<MenuEntity> getMenuByPostCode(String appId, String postCode, String menuType, String menuId) {
		List<MenuEntity> list = menuDao.getMenuByPostCode(appId, postCode, menuType, menuId);
		return list;
	}

	@Override
	public List<MenuEntity> getMenuBuCode(String menuCode, String postCode,String appId,String menuType) {
		List<MenuEntity> list = menuDao.getMenuCode(menuCode,postCode,appId,menuType);
		return list;
	}

	@Override
	public Map<String,Object> getButtonByCode(String appId, String postCode, String menuCode) {
		HashMap<String, Object> rs = Maps.newHashMap();
		//有权限操作的按钮
		List<MenuEntity> operationButtonlist = menuDao.getMenuBuCode(menuCode,postCode,appId,"button");
		//当前菜单下所有按钮
		List<MenuEntity> buttonList = menuDao.getButtonByMenuCode(menuCode);
		for (MenuEntity menuEntity:
				buttonList) {
			rs.put(menuEntity.getMenuCode(),false);
			for (MenuEntity opreationMenuEntity:
					operationButtonlist) {
				if(StringUtil.notEmpty(opreationMenuEntity.getMenuCode()) &&
						StringUtil.notEmpty(menuEntity.getMenuCode()) &&
						opreationMenuEntity.getMenuCode().equals(menuEntity.getMenuCode())
				){
					rs.put(menuEntity.getMenuCode(),true);
					continue;
				}
			}
		}
		return rs;
	}

	@Override
	public List<MenuEntity> getMenListByAppId(String appId) {
		return this.baseMapper.findMenuList(appId);
	}

	@Override
	public void deleteMenuByAppId(String appId) {
		this.baseMapper.deleteMenuByAppId(appId);
	}

	private LambdaQueryWrapper<TPfMenu> buildQueryWrapper(MenuEntity bo) {
		LambdaQueryWrapper<TPfMenu> lqw = Wrappers.lambdaQuery();
		lqw.eq(ObjectUtil.isNotEmpty(bo.getMenuId()), TPfMenu::getMenuId, bo.getMenuId());
		lqw.eq(ObjectUtil.isNotEmpty(bo.getAppId()), TPfMenu::getAppId, bo.getAppId());
		lqw.eq(ObjectUtil.isNotEmpty(bo.getMenuParentId()), TPfMenu::getMenuParentId, bo.getMenuParentId());
		lqw.eq(ObjectUtil.isNotEmpty(bo.getMenuCode()), TPfMenu::getMenuCode, bo.getMenuCode());
		lqw.like(ObjectUtil.isNotEmpty(bo.getMenuName()), TPfMenu::getMenuName, bo.getMenuName());
		lqw.eq(ObjectUtil.isNotEmpty(bo.getMenuType()), TPfMenu::getMenuType, bo.getMenuType());
		lqw.eq(ObjectUtil.isNotEmpty(bo.getMenuIcon()), TPfMenu::getMenuIcon, bo.getMenuIcon());
		lqw.eq(ObjectUtil.isNotEmpty(bo.getMenuUrl()), TPfMenu::getMenuUrl, bo.getMenuUrl());
		lqw.eq(ObjectUtil.isNotEmpty(bo.getStatus()), TPfMenu::getStatus, bo.getStatus());
		lqw.eq(ObjectUtil.isNotEmpty(bo.getCreatorId()), TPfMenu::getCreatorId, bo.getCreatorId());
		lqw.eq(ObjectUtil.isNotEmpty(bo.getUpdatorId()), TPfMenu::getUpdatorId, bo.getUpdatorId());
		lqw.like(ObjectUtil.isNotEmpty(bo.getRemark()), TPfMenu::getRemark, bo.getRemark());
		lqw.eq(ObjectUtil.isNotEmpty(bo.getMenuLevel()), TPfMenu::getMenuLevel, bo.getMenuLevel());
		return lqw;
	}

}
