package com.ruoyi.framework.web.service;

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

import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.enums.MenuRangeEnum;
import com.ruoyi.common.enums.MenuStatusEnum;
import com.ruoyi.common.enums.MenuTypeEnum;
import com.ruoyi.common.enums.MenuVisibleEnum;
import com.ruoyi.system.mapper.system.SysMenuMapper;
import com.ruoyi.system.service.system.SysMenuPermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.service.system.ISysMenuService;
import com.ruoyi.system.service.system.ISysRoleService;

/**
 * 用户权限处理
 *
 * @author ruoyi
 */
@Component
public class SysPermissionService {
    @Autowired
    private ISysRoleService roleService;

    @Autowired
    private ISysMenuService menuService;

    @Autowired
    private SysMenuPermissionService sysMenuPermissionService;

    @Autowired
    private SysMenuMapper menuMapper;

    /**
     * 获取角色数据权限
     *
     * @param user 用户信息
     * @return 角色权限信息
     */
    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;
    }

    /**
     * 获取菜单数据权限(PC)
     *
     * @param user 用户信息
     * @return 菜单权限信息 perms ("*:*:*")
     */
    public Set<String> getMenuPermission(SysUser user) {
        Set<String> perms = new HashSet<String>();
        // 管理员拥有所有权限
        if (user.isAdmin()) {
            perms.add("*:*:*");
        } else {
            List<Long> menuIds = sysMenuPermissionService.getUserMenuIds(user, MenuRangeEnum.PC.getCode());
            if (!CollectionUtils.isEmpty(menuIds)) {
                List<SysMenu> menus = menuService.listByMenuIds(menuIds);
                perms.addAll(menus.stream().map(SysMenu::getPerms).collect(Collectors.toSet()));
            }
        }
        return perms;
    }

    /**
     * 获取PC有权限的menu对象list
     * @param user
     * @return
     */
    public List<SysMenu> getMenuPermissionMenuList(SysUser user) {
        List<Long> menuIds;
        // 管理员拥有所有权限
        if (user.isAdmin()) {
            SysMenu sysMenu = new SysMenu();
            sysMenu.setWorkRange(MenuRangeEnum.PC.getCode());
            sysMenu.setStatus("0");
            return menuMapper.selectMenuList(sysMenu);
        } else {
            menuIds = sysMenuPermissionService.getUserMenuIds(user, MenuRangeEnum.PC.getCode());
            if (!CollectionUtils.isEmpty(menuIds)) {
                return menuService.listByMenuIds(menuIds);
            }
        }
        return new ArrayList<>();
    }

    /**
     * 获取菜单数据权限(APP端)(返回Path)
     *
     * @param user 用户信息
     * @return 菜单权限信息
     */
    public Set<String> getAppMenuPermission(SysUser user) {
        Set<String> perms = new HashSet<String>();
        // 管理员拥有所有权限
        if (user.isAdmin()) {
            SysMenu sysMenu = new SysMenu();
            sysMenu.setWorkRange(MenuRangeEnum.APP.getCode());
            sysMenu.setStatus("0");
            List<SysMenu> sysMenuList = menuMapper.selectMenuList(sysMenu);
            perms.addAll(sysMenuList.stream().map(SysMenu::getPath).collect(Collectors.toSet()));
        } else {
            List<Long> menuIds = sysMenuPermissionService.getUserMenuIds(user, MenuRangeEnum.APP.getCode());
            if (!CollectionUtils.isEmpty(menuIds)) {
                List<SysMenu> menus = menuService.listByMenuIds(menuIds);
                perms.addAll(menus.stream().map(SysMenu::getPath).collect(Collectors.toSet()));
            }
        }
        return perms;
    }


    public List<SysMenu> getAppList(SysUser sysUser) {

        // 获取所有的APP
        SysMenu rootParams = new SysMenu();
        rootParams.setParentId(0L);
        rootParams.setVisible(MenuVisibleEnum.VISIBLE.getCode());
        rootParams.setStatus(MenuStatusEnum.OK.getCode());
        rootParams.setMenuType(MenuTypeEnum.APP.getCode());
        List<SysMenu> appList = menuMapper.selectMenuList(rootParams);

        // 角色集合
        List<SysMenu> myAppList = new ArrayList<>();
        Set<String> roles = getRolePermission(sysUser);
        if (roles.contains("admin")) {
            return appList;
        }

        List<Long> menusIds = sysMenuPermissionService.getUserMenuIds(sysUser, MenuRangeEnum.PC.getCode());
        for (SysMenu app : appList) {
            if (menusIds.contains(app.getMenuId())) {
                myAppList.add(app);
            }
        }
        return myAppList;
    }

    public boolean hasAppPerms(SysUser sysUser, Long menuId) {

        Set<String> roles = getRolePermission(sysUser);
        if (roles.contains("admin")) {
            return true;
        }

        List<Long> menusIds = sysMenuPermissionService.getUserMenuIds(sysUser, MenuRangeEnum.PC.getCode());
        for (Long menusId : menusIds) {
            if (menusId.equals(menuId)) {
                return true;
            }
        }
        return false;
    }
}
