
package com.tmerclub.cloud.rbac.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.tmerclub.cloud.common.database.dto.PageDTO;
import com.tmerclub.cloud.common.database.util.PageUtil;
import com.tmerclub.cloud.common.database.vo.PageVO;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.rbac.mapper.RoleMapper;
import com.tmerclub.cloud.rbac.mapper.RoleMenuMapper;
import com.tmerclub.cloud.rbac.mapper.UserRoleMapper;
import com.tmerclub.cloud.rbac.model.Role;
import com.tmerclub.cloud.rbac.model.RoleMenu;
import com.tmerclub.cloud.rbac.service.RoleService;
import com.tmerclub.cloud.rbac.vo.RoleVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 角色
 *
 * @author tmerclub
 * @date 2020-09-17 19:15:44
 */
@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Override
    public PageVO<RoleVO> page(PageDTO pageDTO, Integer sysType, Long tenantId, String roleName) {
        return PageUtil.doPage(pageDTO, () -> roleMapper.list(sysType, tenantId, roleName));
    }

    @Override
    public List<RoleVO> list(Integer sysType, Long tenantId) {
        return roleMapper.list(sysType, tenantId, null);
    }

    @Override
    public RoleVO getByRoleId(Long roleId) {
        RoleVO role = roleMapper.getByRoleId(roleId);
        List<RoleMenu> roleMenus = roleMenuMapper.getByRoleId(roleId);
        role.setMenuIds(roleMenus.stream().map(RoleMenu::getMenuId).filter(Objects::nonNull).collect(Collectors.toList()));
        role.setMenuPermissionIds(roleMenus.stream().map(RoleMenu::getMenuPermissionId).filter(Objects::nonNull).collect(Collectors.toList()));
        return role;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(Role role, List<Long> menuIds, List<Long> menuPermissionIds) {
        if (roleMapper.countRoleName(role) > 0) {
            throw new LuckException("角色名称已存在，请重新输入");
        }
        roleMapper.save(role);
        insertMenuAndPermission(role.getRoleId(), menuIds, menuPermissionIds);
    }


    @Override
    public void update(Role role, List<Long> menuIds, List<Long> menuPermissionIds) {
        if (roleMapper.countRoleName(role) > 0) {
            throw new LuckException("角色名称已存在，请重新输入");
        }
        roleMapper.update(role);
        roleMenuMapper.deleteByRoleId(role.getRoleId());
        insertMenuAndPermission(role.getRoleId(), menuIds, menuPermissionIds);
    }

    private void insertMenuAndPermission(Long roleId, List<Long> menuIds, List<Long> menuPermissionIds) {
        if (CollectionUtil.isNotEmpty(menuIds)) {
            List<RoleMenu> roleMenus = menuIds.stream().map(menuId -> {
                RoleMenu roleMenu = new RoleMenu();
                roleMenu.setRoleId(roleId);
                roleMenu.setMenuId(menuId);
                return roleMenu;
            }).collect(Collectors.toList());
            roleMenuMapper.insertBatch(roleMenus);
        }

        if (CollectionUtil.isNotEmpty(menuPermissionIds)) {
            List<RoleMenu> roleMenus = menuPermissionIds.stream().map(menuPermissionId -> {
                RoleMenu roleMenu = new RoleMenu();
                roleMenu.setRoleId(roleId);
                roleMenu.setMenuPermissionId(menuPermissionId);
                return roleMenu;
            }).collect(Collectors.toList());
            roleMenuMapper.insertBatch(roleMenus);
        }
    }

    @Override
    public void deleteById(Long roleId, Integer sysType) {

        // 获取正在使用中的角色
        List<Long> userRoleIds = userRoleMapper.selectUseRoleIds(roleId);

        if (CollUtil.isNotEmpty(userRoleIds)) {
            RoleVO roleVO = roleMapper.getByRoleId(roleId);
            if (Objects.nonNull(roleVO)) {
                throw new LuckException("角色：" + roleVO.getRoleName() + "使用中不能删除");
            }
        }
        roleMapper.deleteById(roleId, sysType);
        roleMenuMapper.deleteByRoleId(roleId);
        userRoleMapper.deleteByRoleId(roleId);
    }

    @Override
    public Integer getBizType(Long roleId) {
        return roleMapper.getBizType(roleId);
    }
}
