package cn.gintone.service;


import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthPermissionInfoRespVO;
import cn.iocoder.yudao.module.system.convert.auth.AuthConvert;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper;
import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum;
import cn.iocoder.yudao.module.system.service.permission.MenuService;
import cn.iocoder.yudao.module.system.service.permission.RoleService;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
import static cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO.ID_ROOT;

@Service
public class MySystemServiceImpl implements MySystemService {

    @Autowired
    private MenuService menuService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private AdminUserService adminUserService;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Override
    public List<AuthPermissionInfoRespVO.MenuVO> getMenuBySysAbbre(String sysAbbre) {
        if ("secure".equals(sysAbbre)) {
            Set<Long> menuIds = convertSet(menuService.getMenuList(), MenuDO::getId);
            List<MenuDO> menuList = menuService.getMenuList(menuIds);
            menuList = menuService.filterDisableMenus(menuList);
            List<AuthPermissionInfoRespVO.MenuVO> menuVOS = buildMenuTree(menuList);
            return menuVOS;
        } else {
            return CollUtil.newArrayList();
        }
    }

    @Override
    public List<RoleDO> getRolesBySysAbbre(String sysAbbre) {
        if ("secure".equals(sysAbbre)) {
            return roleService.getRoleList();
        } else {
            return CollUtil.newArrayList();
        }
    }

    @Override
    public List<AdminUserDO> getAdminUsersBySysAbbreAndRoleId(String sysAbbre, String roleId) {
        List<AdminUserDO> adminUserDOList = new ArrayList<>();
        if ("secure".equals(sysAbbre)) {
            List<Long> roleIds = new ArrayList<>();
            roleIds.add(Long.valueOf(roleId));
            List<UserRoleDO> userRoleDOS = userRoleMapper.selectListByRoleIds(roleIds);
            if (null != userRoleDOS && userRoleDOS.size() > 0) {
                for (UserRoleDO userRoleDO : userRoleDOS) {
                    Long userId = userRoleDO.getUserId();
                    AdminUserDO user = adminUserService.getUser(userId);
                    adminUserDOList.add(user);
                }
            }
            return adminUserDOList;
        }

        return Collections.emptyList();
    }


    public List<AuthPermissionInfoRespVO.MenuVO> buildMenuTree(List<MenuDO> menuList) {
        if (CollUtil.isEmpty(menuList)) {
            return Collections.emptyList();
        }
        // 移除按钮
        menuList.removeIf(menu -> menu.getType().equals(MenuTypeEnum.BUTTON.getType()));
        // 排序，保证菜单的有序性
        menuList.sort(Comparator.comparing(MenuDO::getSort));

        // 构建菜单树
        // 使用 LinkedHashMap 的原因，是为了排序 。实际也可以用 Stream API ，就是太丑了。
        Map<Long, AuthPermissionInfoRespVO.MenuVO> treeNodeMap = new LinkedHashMap<>();
        menuList.forEach(menu -> treeNodeMap.put(menu.getId(), AuthConvert.INSTANCE.convertTreeNode(menu)));
        // 处理父子关系
        treeNodeMap.values().stream().filter(node -> !node.getParentId().equals(ID_ROOT)).forEach(childNode -> {
            // 获得父节点
            AuthPermissionInfoRespVO.MenuVO parentNode = treeNodeMap.get(childNode.getParentId());
            if (parentNode == null) {
                LoggerFactory.getLogger(getClass()).error("[buildRouterTree][resource({}) 找不到父资源({})]",
                        childNode.getId(), childNode.getParentId());
                return;
            }
            // 将自己添加到父节点中
            if (parentNode.getChildren() == null) {
                parentNode.setChildren(new ArrayList<>());
            }
            parentNode.getChildren().add(childNode);
        });
        // 获得到所有的根节点
        return filterList(treeNodeMap.values(), node -> ID_ROOT.equals(node.getParentId()));
    }
}
