package com.xy.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xy.dto.SysRoleDto;
import com.xy.entity.SysRoleMenu;
import com.xy.mapper.SysRoleMenuMapper;
import com.xy.service.SysRoleMenuService;
import com.xy.utils.Beans;
import com.xy.vo.RoleMenuVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/***
 * 角色菜单表
 * @author 谭斌
 * @date 2022/12/13 9:21
 */
@Service
public class SysRoleMenuServiceImpl extends ServiceImpl<SysRoleMenuMapper, SysRoleMenu> implements SysRoleMenuService {

    /**
     * 更新角色菜单权限
     *
     * @param roleMenuVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveRoleMenus(RoleMenuVo roleMenuVo) {
        Long roleId = roleMenuVo.getId();
        List<Long> menuIds = roleMenuVo.getMenuIds();
        Long sysId = roleMenuVo.getSysId();
        //移除旧的权限
        remove(Wrappers.<SysRoleMenu>query().lambda().eq(SysRoleMenu::getRoleId, roleId));

        if (CollectionUtil.isEmpty(menuIds)) {
            return Boolean.TRUE;
        }
        //封装角色菜单权限
        List<SysRoleMenu> roleMenuList = menuIds.stream().map(menuId -> {
            SysRoleMenu roleMenu = new SysRoleMenu();
            roleMenu.setRoleId(roleId);
            roleMenu.setMenuId(menuId);
            roleMenu.setSysId(sysId).createId();
            return roleMenu;
        }).collect(Collectors.toList());
        //批量保存
        return saveBatch(roleMenuList);
    }

    @Override
    public List<Long> getMenuIdsByRoleId(Long roleId, Boolean isAdmin) {
        List<Long> menuIds = new ArrayList<>(16);
        List<SysRoleMenu> sysRoleMenus = this.list(Wrappers.<SysRoleMenu>lambdaQuery()
                .eq(SysRoleMenu::getRoleId, roleId)
                .eq(isAdmin != null, SysRoleMenu::getSelectAdmin, isAdmin)
        );
        if (CollUtil.isEmpty(sysRoleMenus)) {
            return menuIds;
        }
        menuIds = sysRoleMenus.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());
        return menuIds;
    }

    @Override
    public Boolean updateAdminRoleMenu(SysRoleDto.UpdateAdminRoleMenu updateAdminRoleMenu) {
        List<SysRoleMenu> sysRoleMenuList = Beans.copy(SysRoleMenu.class, updateAdminRoleMenu.getRoleMenuList());
        if (CollUtil.isEmpty(sysRoleMenuList)) {
            return Boolean.TRUE;
        }
        SysRoleMenu reqSysRoleMenu = sysRoleMenuList.get(0);
        //先将现有的管理员权限全部更新为false，因为前端只传全量的有管理员权限的菜单
        List<SysRoleMenu> roleMenuList = this.list(
                Wrappers.<SysRoleMenu>lambdaQuery().eq(SysRoleMenu::getSysId, reqSysRoleMenu.getSysId())
                        .eq(SysRoleMenu::getRoleId, reqSysRoleMenu.getRoleId()));

        if (CollUtil.isNotEmpty(roleMenuList)) {
            List<SysRoleMenu> updateRoleMenuList = roleMenuList.stream().map(sysRoleMenu -> {
                sysRoleMenu.setSelectAdmin(Boolean.FALSE);
                return sysRoleMenu;
            }).collect(Collectors.toList());
            updateBatchById(updateRoleMenuList);
        }

        List<SysRoleMenu> updateList = new ArrayList<>(16);
        List<SysRoleMenu> addList = new ArrayList<>(16);
        sysRoleMenuList.forEach(sysRoleMenu -> {
            SysRoleMenu roleMenu = this.getOne(Wrappers.<SysRoleMenu>lambdaQuery()
                    .eq(SysRoleMenu::getSysId, sysRoleMenu.getSysId())
                    .eq(SysRoleMenu::getRoleId, sysRoleMenu.getRoleId())
                    .eq(SysRoleMenu::getMenuId, sysRoleMenu.getMenuId())
            );
            if (roleMenu != null) {
                updateList.add(roleMenu.setSelectAdmin(Boolean.TRUE));
            } else {
                addList.add(sysRoleMenu.createId().setSelectAdmin(Boolean.TRUE));
            }
        });
        if (CollUtil.isNotEmpty(updateList)) {
            updateBatchById(updateList);
        }
        if (CollUtil.isNotEmpty(addList)) {
            saveBatch(addList);
        }
        return Boolean.TRUE;
    }

}
