package cn.service.system.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import cn.common.exception.BaseException;
import cn.orm.abs.ISqlToyDao;
import cn.orm.sqltoy.plus.Wrappers;
import cn.orm.sqltoy.plus.query.LambdaQueryWrapper;
import cn.orm.sqltoy.plus.query.QueryWrapper;
import cn.pojo.entity.TSysRole;
import cn.pojo.entity.TSysRoleDept;
import cn.pojo.entity.TSysRoleMenu;
import cn.pojo.entity.TSysRolePerm;
import cn.pojo.entity.TSysUser;
import cn.pojo.entity.TSysMenu;
import cn.service.system.IRoleService;
import cn.util.core.IsKit;
import cn.util.core.TypeKit;
import cn.util.string.StringKit;

@Repository("IRoleService")
public class RoleServiceImpl implements IRoleService
{	
	@Autowired
	private ISqlToyDao daoService;
	
	/**
	 * 修改保存角色权限信息表
	 * 角色信息role_id menu_id
	 * @return 结果
	 */
	@Override
	public Map<String,Object> getRolePerms(Map<String, Object> whereMap)
	{
		return daoService.getMap("t_sys_role_perm","perm",whereMap);
	}
	/**查询全部角色权限信息*/
	@Override
	public List<Map<String, Object>> getRolePermList()
	{
		List<Map<String, Object>> resultList = new ArrayList<>();
		resultList = TypeKit.cast(daoService.findBySql("sys_queryRolePerm",null,Map.class));
		if(IsKit.isNullOrEmpty(resultList)){
			return resultList;
		}
		for(int i = 0; i<resultList.size();++i) 
		{
			Map<String, Object> map = (Map<String, Object>) resultList.get(i); 
			String oMenuIds = TypeKit.objToStr(map.get("menuId"));
			//约定0 表示全选
			if("0".equals(oMenuIds)) {
				map.put("menuName", "全部");
				continue;
			}
			oMenuIds = StringKit.removeBracket(oMenuIds);
			QueryWrapper<TSysMenu> wrapper = Wrappers.wrapper(TSysMenu.class)
					.select("GROUP_CONCAT(meta_title SEPARATOR ',') AS metaTitle")
			        .in("menuId",Arrays.asList(oMenuIds.split(",")));
			TSysMenu entity = daoService.findOne(wrapper);
			if(IsKit.isNullOrEmpty(entity)){
				map.put("menuName", "");
			}
			else {
				map.put("menuName", entity.getMetaTitle());
			}
		}
		return TypeKit.cast(resultList);
	}
	/** 判断给定角色和菜单所对应的按钮权限是否存在: 存在返回TRUE
	 * {"roleId":1,"menuId":[5,80,801,802,803,804,8041,8042,805,806,807,808,809]}
	 * */
	@Override
	public Boolean ifExistRoleMenuPerm(Integer roleId,String nMenuIds)
	{
		LambdaQueryWrapper<TSysRolePerm> wrapper = Wrappers.lambdaWrapper(TSysRolePerm.class)
				.select(TSysRolePerm::getMenuId)
				.eq(TSysRolePerm::getRoleId,roleId);
		List<TSysRolePerm> entityList = daoService.findList(wrapper);
		if(IsKit.isNullOrEmpty(entityList)) {
			return false;
		}
		ArrayList<String> nMenuList = new ArrayList<String>(Arrays.asList(nMenuIds.split(",")));
		Boolean result= false;
		for(TSysRolePerm entity: entityList)
		{
			String oMenuIds = entity.getMenuId();
			if(IsKit.isNullOrEmpty(oMenuIds)) {
				continue;
			}
			ArrayList<String> oMenuList = new ArrayList<String>(Arrays.asList(oMenuIds.split(",")));
			//相等：应该进行更新操作
			if(nMenuList.equals(oMenuList)){
				return false;
			}
			//求交集 结果放在oMenuList
			oMenuList.retainAll(nMenuList);
			//交集空，表示针对本次循环可以保存
			if(IsKit.isNullOrEmpty(oMenuList)){
				continue;
			}
			//存在交集.
			for(String num: oMenuList) {
				//t_sys_menu表中menu_id约定：一级菜单两位数以内
				if(num.length() > 2) {
					result = true;
					break;
				}
			}
			if(result) {
				break;
			}    
		}
		return result;
	}
	/**
	 * 修改保存角色权限信息表
	 * @param role 角色信息
	 * @return 结果
	 */
	@Override
	public Long updateRolePerm(TSysRolePerm role) {
		return daoService.saveOrUpdate(role);
	}
	/**
	 * 修改保存角色菜单信息表
	 * @param role 角色信息
	 * @return 结果
	 */
	@Override
	public Long updateRoleMenu(TSysRole role) 
	{
		//先删除与此角色相关关联所有菜单。涉及表：t_sys_role_menu
		deleteRoleMenuByRoleId(role.getRoleId().longValue());
		//重新插入角色与菜单关联关系。涉及表：t_sys_role_menu
		return _insertRoleMenu(role);
	}
	
	/**
	 * 通过角色ID删除角色和菜单关联项 表：t_sys_role_menu
	 * @param roleId 角色ID
	 * @return 结果
	 */
	@Override
	public Boolean deleteRoleMenuByRoleId(Long roleId) 
	{
		LambdaQueryWrapper<TSysRoleMenu> wrapper = Wrappers.lambdaWrapper(TSysRoleMenu.class)
		        .eq(TSysRoleMenu::getRoleId,roleId);
		return daoService.delete(wrapper) > 0 ? true:false;
	}
	
	/**
	 * 校验角色是否唯一
	 * @param role 角色信息
	 * @return 结果 0 校验是唯一的, 1 角色名不唯一, 2角色权限不唯一
	 */
	@Override
	public int checkRoleUnique(TSysRole role)
	{
		int count = 0;
		LambdaQueryWrapper<TSysRole> queryWrapper = Wrappers.lambdaWrapper(TSysRole.class)
				.select(TSysRole::getRoleKey)//角色权限2
				.select(TSysRole::getRoleName)//角色名称1
				.select(TSysRole::getRoleId)
				.ne(TSysRole::getDelFlag,"1")
				.eq(TSysRole::getRoleId,role.getRoleId());
		
		List<TSysRole> sysRoles = daoService.findList(queryWrapper);
		if (IsKit.isNullOrEmpty(sysRoles)) {
			return count;
		}
		for (TSysRole sysUser : sysRoles)
		{
			if (sysUser.getRoleId().intValue() != role.getRoleId().intValue()){
				if (sysUser.getRoleName().equals(role.getRoleName())) {
					return count = 1;
				} else if (sysUser.getRoleKey().equals(role.getRoleKey())) {
					return count = 2;
				}
			}
		}
		return count;
	}
	/**
	 * 新增角色菜单信息 表：t_sys_role_menu
	 * @param role 角色对象 menuIds=[80, 801, 802], roleId=1
	 */
	private Long _insertRoleMenu(TSysRole role) 
	{
		Long rows = -1l;
		// 新增用户与角色管理
		List<TSysRoleMenu> list = new ArrayList<TSysRoleMenu>();
		for (Integer menuId : role.getMenuIds()) {
			TSysRoleMenu rm = new TSysRoleMenu();
			rm.setRoleId(role.getRoleId());
			rm.setMenuId(menuId);
			list.add(rm);
		}
		if (list.size() > 0) {
			rows = _batchRoleMenu(list);
		}
		return rows;
	}
	/**
	 * 批量新增角色菜单信息
	 * @param roleMenuList 角色菜单列表
	 * @return 结果
	 */
	private Long _batchRoleMenu(List<TSysRoleMenu> roleMenuList) {
		return daoService.saveAll(roleMenuList);
	}

	
	/** 保留：批量删除角色信息
	 * @param roleIds 需要删除的角色ID
	 * @return 结果
	 */
	@Override
	public int deleteRoleByIds(Long[] roleIds) 
	{
		int count = 0;
		for (Long roleId : roleIds) 
		{
			LambdaQueryWrapper<TSysRole> wrapper = Wrappers.lambdaWrapper(TSysRole.class)
			        .eq(TSysRole::getRoleId,roleId) ;
			TSysRole sysRole = daoService.findOne(wrapper);
			//保证一人一个角色？
			if (countUserRoleByRoleId(roleId)) {
				throw new BaseException(String.format("%1$s已分配,不能删除", sysRole.getRoleName()));
			}            
			//删除角色与菜单关联
			deleteRoleMenuByRoleId(roleId);

			// 删除角色与部门关联
			deleteRoleDeptByRoleId(roleId);
			//TSysRole sysRole = baseMapper.selectById(roleId);
			//baseMapper.updateById(sysRole);
			sysRole.setDelFlag("2");
			daoService.update(sysRole, "del_flag");
			count++;
		}
		return count;
	}
	
	/**
	 * 保留：新增保存角色信息
	 * @param role 角色信息
	 * @return 结果
	 */
	@Override
	public Long insertRole(TSysRole role) {
		daoService.save(role);
		return _insertRoleMenu(role);
	}

	/**保留：根据角色编号获取详细信息*/
	@Override
	public TSysRole getById(Long roleId) 
	{
		LambdaQueryWrapper<TSysRole> wrapper = Wrappers.lambdaWrapper(TSysRole.class)
		        .eq(TSysRole::getRoleId,roleId) ;
		return daoService.findOne(wrapper);
	}
	/**保留：通过角色ID查询角色使用数量*/
	@Override
	public Boolean countUserRoleByRoleId(Long roleId) {
		LambdaQueryWrapper<TSysUser> wrapper = Wrappers.lambdaWrapper(TSysUser.class)
		        .like(TSysUser::getRoleIds,roleId) ;
		return daoService.count(wrapper)>0?true:false;
	}  
	/**保留：通过角色ID删除角色和部门关联*/
	@Override
	public Boolean deleteRoleDeptByRoleId(Long roleId) 
	{
		LambdaQueryWrapper<TSysRoleDept> wrapper = Wrappers.lambdaWrapper(TSysRoleDept.class)
		        .eq(TSysRoleDept::getRoleId,roleId) ;
		Long result = daoService.delete(wrapper);
		return result>0? true:false; 
	}


	/**保留：修改数据权限信息*/
	@Override
	public Long authDataScope(TSysRole role) {
		// 修改角色信息
		daoService.update(role);
		// 删除角色与部门关联
		deleteRoleDeptByRoleId(role.getRoleId().longValue());
		// 新增角色和部门信息（数据权限）
		return insertRoleDept(role);
	}
	/**保留：新增角色部门信息(数据权限)*/
	public Long insertRoleDept(TSysRole role) {
		Long rows = 1l;
		// 新增角色与部门（数据权限）管理
		List<TSysRoleDept> list = new ArrayList<TSysRoleDept>();
		for (Integer deptId : role.getDeptIds()) {
			TSysRoleDept rd = new TSysRoleDept();
			rd.setRoleId(role.getRoleId());
			rd.setDeptId(deptId);
			list.add(rd);
		}
		if (list.size() > 0) {
			rows = batchRoleDept(list);
		}
		return rows;
	}
	/**保留：批量新增角色部门信息*/
	public Long batchRoleDept(List<TSysRoleDept> roleDeptList) {
		return daoService.saveAllIgnoreExist(roleDeptList);
	}
}

