package com.vctgo.system.service.impl;

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

import com.alibaba.nacos.shaded.com.google.common.base.Splitter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.vctgo.common.core.web.domain.TenantEntity;
import com.vctgo.common.security.utils.SecurityUtils;
import com.vctgo.system.api.domain.SysRole;
import com.vctgo.system.domain.SysAdminManage;
import com.vctgo.system.domain.SysMenu;
import com.vctgo.system.mapper.SysAdminManageMapper;
import com.vctgo.system.mapper.SysMenuMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.vctgo.system.api.domain.SysUser;
import com.vctgo.system.service.ISysMenuService;
import com.vctgo.system.service.ISysPermissionService;
import com.vctgo.system.service.ISysRoleService;
import org.springframework.util.CollectionUtils;

@Service
public class SysPermissionServiceImpl implements ISysPermissionService {
    @Autowired
    private ISysRoleService roleService;

    @Autowired
    private ISysMenuService menuService;

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Autowired
    private SysAdminManageMapper sysAdminManageMapper;

    /**
     * 获取角色数据权限
     * <p>
     * //     * @param userId 用户Id
     *
     * @return 角色权限信息
     */
    @Override
    public Set<String> getRolePermission(SysUser user) {
        Set<String> roles = new HashSet<String>();
        // 管理员拥有所有权限
        if (user.isAdmin()) {
            roles.add("admin");
        } else {
            roles.addAll(roleService.selectRolePermissionByUserId(user.getUserId()));
        }
        return roles;
    }

    /**
     * 获取菜单数据权限
     *
     * @param user 用户Id
     * @return 菜单权限信息
     */
    @Override
    public Set<String> getMenuPermission(SysUser user) {
        Set<String> perms = new HashSet<>();
        // 管理员拥有所有权限
        if (user.isAdmin()) {
            perms.add("*:*:*");
        } else {
            List<SysRole> roles = user.getRoles();
            List<String> roleKeyList = roles.stream().map(SysRole::getRoleKey).collect(Collectors.toList());
            if (roleKeyList.contains("admin")) {

                // 获取超管菜单
                List<SysAdminManage> sysAdminManageList = sysAdminManageMapper.selectList();
                LambdaQueryWrapper<SysMenu> sysMenuWrapper = new LambdaQueryWrapper<>();
                sysMenuWrapper.eq(SysMenu::getStatus, "0");
                sysMenuWrapper.in(SysMenu::getMenuId, Splitter.on(",").splitToList(sysAdminManageList.get(0).getMenuIds()));
                return sysMenuMapper.selectList(sysMenuWrapper).stream().map(SysMenu::getPerms).collect(Collectors.toSet());
            }

            if (!roles.isEmpty() && roles.size() > 1) {
                // 多角色设置permissions属性，以便数据权限匹配权限
                for (SysRole role : roles) {
                    Set<String> rolePerms = menuService.selectMenuPermsByRoleId(role.getRoleId());
                    role.setPermissions(rolePerms);
                    perms.addAll(rolePerms);
                }
            } else {
                perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId()));
            }

            String menuIds = sysMenuMapper.selectMenuListByTenantId(SecurityUtils.getTenantId());
            SysMenu sysMenu = new SysMenu();
            sysMenu.setMenuIds(menuIds);
            List<SysMenu> sysMenuList = sysMenuMapper.selectMenuListByMenuId(sysMenu);
            List<String> permissionsList = sysMenuList.stream().map(SysMenu::getPerms).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(permissionsList)) {
                HashSet<String> setPermissions = new HashSet<>(permissionsList);
                perms.removeIf(permission -> !setPermissions.contains(permission));
            }
        }
        return perms;
    }

    /**
     * 考虑集团租户场景下--多租户多角色获取菜单数据权限
     *
     * @param user 用户Id
     * @return 菜单权限信息
     */
    @Override
    public Set<String> getMenuPermissionByMultiTenant(SysUser user) {
        Set<String> perms = new HashSet<>();
        // 管理员拥有所有权限
        if (user.isAdmin()) {
            perms.add("*:*:*");
        } else {
            // 多个租户多个角色Permissions属性，依托于菜单的正确性，而忽略此方法的严谨性
            SecurityUtils.setTemporaryIgnoreTables(Arrays.asList("sys_menu", "m", "sys_role_menu", "rm"));
            for (SysRole role : user.getRoles()) {
                Set<String> rolePerms = menuService.selectMenuPermsByRoleId(role.getRoleId());
                role.setPermissions(rolePerms);
                perms.addAll(rolePerms);
            }
            SecurityUtils.removeTemporaryIgnoreTables(Arrays.asList("sys_menu", "m", "sys_role_menu", "rm"));
            if (9999L != SecurityUtils.getTenantId() && CollectionUtils.isEmpty(perms)) {
                String menuIds = sysMenuMapper.selectMenuListByTenantId(SecurityUtils.getTenantId());
                SysMenu sysMenu = new SysMenu();
                sysMenu.setMenuIds(menuIds);
                List<SysMenu> sysMenuList = sysMenuMapper.selectMenuListByMenuId(sysMenu);
                return sysMenuList.stream().map(SysMenu::getPerms).map(String::valueOf).collect(Collectors.toSet());
                // 优化---使用所有角色对应的所有权限进行过滤，把角色删除掉的权限过滤掉
            }
        }
        return perms;
    }
}
