/**
 * 
 */
package org.springblade.modules.system.service.normal;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.springblade.core.tool.utils.Func;
import org.springblade.modules.system.entity.DataPermission;
import org.springblade.modules.system.entity.DataPermissionDept;
import org.springblade.modules.system.entity.DataPermissionRole;
import org.springblade.modules.system.entity.DataPermissionUser;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.mapper.DataPermissionMapper;
import org.springblade.modules.system.service.IUserService;
import org.springblade.modules.system.vo.UserVO;
import org.springblade.system.client.dto.DataPermDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;

/**
 * @author wookvn
 *
 */
@Service
public class DataPermissionService extends ServiceImpl<DataPermissionMapper, DataPermission> {

//	@Autowired
//	private IUserService userService;
	
	@Autowired
	private DataPermissionUserService dataPermissionUserService;
	
	@Autowired
	private DataPermissionRoleService dataPermissionRoleService;
	
	@Autowired
	private DataPermissionDeptService dataPermissionDeptService;
	
	public List<UserVO> selectDataPerms(List<Long> userIdList){
		return baseMapper.selectDataPerms(userIdList);
	}
	
	@Transactional
	public boolean doSaveOrUpdate(DataPermission dataPermission) {
		DataPermDto dataPermDto = JSON.parseObject(dataPermission.getPermJson(), DataPermDto.class);
		Set<Long> userIdSet = new HashSet<>();
		List<Long> deptIdList = new ArrayList<>(),
				   roleIdList = new ArrayList<>(),
				   userIdList = new ArrayList<>();
		//设置的部门
		if(CollectionUtil.isNotEmpty(dataPermDto.getDpList())) {
			dataPermDto.getDpList().stream().filter(x -> StrUtil.isNotBlank(x.getId())).map(t -> Long.parseLong(t.getId())).forEach(deptIdList::add);
			if(CollectionUtil.isNotEmpty(deptIdList)) {
				List<User> userList = SpringUtil.getBean(IUserService.class).selectUserIdListByDeptIdList(deptIdList);
				if(CollectionUtil.isNotEmpty(userList)) {
					userList.stream().map(User::getId).forEach(userIdSet::add);
				}
			}
		}
		//设置的角色
		if(CollectionUtil.isNotEmpty(dataPermDto.getRoleList())) {
			dataPermDto.getRoleList().stream().filter(x -> StrUtil.isNotBlank(x.getId())).map(t -> Long.parseLong(t.getId())).forEach(roleIdList::add);
			if(CollectionUtil.isNotEmpty(roleIdList)) {
				roleIdList.forEach(roleId -> {
					List<User> userList = SpringUtil.getBean(IUserService.class).selectUserIdListByRoleId(roleId);
					if(CollectionUtil.isNotEmpty(userList)) {
						userList.stream().map(User::getId).forEach(userIdSet::add);
					}
				});
			}
		}
		//设置的用户
		if(CollectionUtil.isNotEmpty(dataPermDto.getUserList())) {
			userIdList = dataPermDto.getUserList().stream().filter(x -> StrUtil.isNotBlank(x.getId())).map(t -> Long.parseLong(t.getId())).collect(Collectors.toList());
			userIdSet.addAll(userIdList);
		}
		//设置的黑名单用户
		if(CollectionUtil.isNotEmpty(dataPermDto.getBlackUserList())) {
			userIdSet.removeIf(userId -> dataPermDto.getBlackUserList().stream().anyMatch(blackUser -> userId.longValue() == Long.valueOf(blackUser.getId())));
		}
		boolean ret = saveOrUpdate(dataPermission);
		if(ret) {
			int dataPermId = dataPermission.getId();
			/*** ----添加用户关联表---- **/
			//先删除，再添加
			dataPermissionUserService.remove(Wrappers.<DataPermissionUser>lambdaQuery().eq(DataPermissionUser::getDataPermId, dataPermId));
			//组装用户ID和权限组的关系
			List<DataPermissionUser> dataList = new ArrayList<>(userIdSet.size());
			for(Long userId : userIdSet) {
				//判断用户ID是否直接设置的
				Integer userStatus = !userIdList.isEmpty() && userIdList.contains(userId) ? 1 : 0;
				dataList.add(new DataPermissionUser(null, dataPermId, userId, userStatus));
			}
			if(CollectionUtil.isNotEmpty(dataList)) {
				dataPermissionUserService.saveBatch(dataList);
			}
			/*** ----添加角色关联表---- **/
			dataPermissionRoleService.remove(Wrappers.<DataPermissionRole>lambdaQuery().eq(DataPermissionRole::getDataPermId, dataPermId));
			List<DataPermissionRole> permRoleList = new ArrayList<>();
			roleIdList.forEach(roleId -> permRoleList.add(new DataPermissionRole(null, roleId, dataPermId)));
			if(CollectionUtil.isNotEmpty(permRoleList)) {
				dataPermissionRoleService.saveBatch(permRoleList);
			}
			/*** ----添加部门关联表---- **/
			dataPermissionDeptService.remove(Wrappers.<DataPermissionDept>lambdaQuery().eq(DataPermissionDept::getDataPermId, dataPermId));
			List<DataPermissionDept> permDeptList = new ArrayList<>();
			deptIdList.forEach(deptId -> permDeptList.add(new DataPermissionDept(null, deptId, dataPermId)));
			if(CollectionUtil.isNotEmpty(permDeptList)) {
				dataPermissionDeptService.saveBatch(permDeptList);
			}
		}
		return ret;
	}

	/**
	 * 更新角色
	 * @param userId
	 * @param roleIdList
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class)
	public boolean doUpdateRole(Long userId, List<Long> roleIdList) {
		User user = SpringUtil.getBean(IUserService.class).getById(userId);
		List<Long> deptIdList = Func.toLongList(user.getDeptId());
		return doUpdateRoleOrDept(userId, roleIdList, deptIdList);
	}
	
	/**
	 * 更新部门
	 * @param userId
	 * @param deptIdList
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class)
	public boolean doUpdateDept(Long userId, List<Long> deptIdList) {
		User user = SpringUtil.getBean(IUserService.class).getById(userId);
		List<Long> roleIdList = Func.toLongList(user.getRoleId());
		return doUpdateRoleOrDept(userId, roleIdList, deptIdList);
	}
	/**
	 * 用户更新部门或者角色
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class)
	public boolean doUpdateRoleOrDept(Long userId, List<Long> roleIdList, List<Long> deptIdList) {
		//先查询出来直接设置用户的权限组
		LambdaQueryWrapper<DataPermissionUser> queryWrapper = Wrappers.<DataPermissionUser>lambdaQuery().select(DataPermissionUser::getDataPermId).eq(DataPermissionUser::getUserId, userId).eq(DataPermissionUser::getUserStatus, 1);
		List<Integer> dataPermIdList = dataPermissionUserService.listObjs(queryWrapper, t -> Integer.valueOf(t.toString()));
		Set<Integer> allDataPermIdSet = new HashSet<>();
		allDataPermIdSet.addAll(dataPermIdList);
		//删除这个人关联的所有权限组
		dataPermissionUserService.remove(Wrappers.<DataPermissionUser>lambdaQuery().eq(DataPermissionUser::getUserId, userId));
		//查询角色都有哪些权限组
		if(CollectionUtil.isNotEmpty(roleIdList)) {
			LambdaQueryWrapper<DataPermissionRole> roleQueryWrapper = Wrappers.<DataPermissionRole>lambdaQuery().select(DataPermissionRole::getDataPermId).in(DataPermissionRole::getRoleId, roleIdList);
			allDataPermIdSet.addAll(dataPermissionRoleService.listObjs(roleQueryWrapper, t -> Integer.valueOf(t.toString())));
		}
		//查询部门都有哪些权限组
		if(CollectionUtil.isNotEmpty(deptIdList)) {
			LambdaQueryWrapper<DataPermissionDept> roleQueryWrapper = Wrappers.<DataPermissionDept>lambdaQuery().select(DataPermissionDept::getDataPermId).in(DataPermissionDept::getDeptId, deptIdList);
			allDataPermIdSet.addAll(dataPermissionDeptService.listObjs(roleQueryWrapper, t -> Integer.valueOf(t.toString())));
		}
		if(!allDataPermIdSet.isEmpty()) {
			List<DataPermissionUser> dataList = new ArrayList<>(allDataPermIdSet.size());
			for(Integer dataPermId : allDataPermIdSet) {
				//判断用户ID是否直接设置的
				Integer userStatus = !dataPermIdList.isEmpty() && dataPermIdList.contains(dataPermId) ? 1 : 0;
				dataList.add(new DataPermissionUser(null, dataPermId, userId, userStatus));
			}
			if(CollectionUtil.isNotEmpty(dataList)) {
				dataPermissionUserService.saveBatch(dataList);
			}
		}
		return true;
	}
	
	@Transactional
	public boolean doRemove(Integer dataPermId) {
		boolean ret = removeById(dataPermId);
		if(ret) {
			dataPermissionUserService.remove(Wrappers.<DataPermissionUser>lambdaQuery().eq(DataPermissionUser::getDataPermId, dataPermId));
		}
		return ret;
	}

	/**
	 * 查询自己所属的权限组【去掉：超级权限组】
	 * @param userId
	 * @return
	 */
	public List<DataPermission> listOwner(Long userId){
		return baseMapper.selectOwnerList(userId);
	}
}
