package com.ema.admin.modules.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.ema.admin.modules.system.converter.SysMenuConverter;
import com.ema.admin.modules.system.entity.SysMenu;
import com.ema.admin.modules.system.entity.SysRole;
import com.ema.admin.modules.system.entity.SysRoleMenu;
import com.ema.admin.modules.system.mapper.SysMenuMapper;
import com.ema.admin.modules.system.service.SysMenuService;
import com.ema.admin.modules.system.service.SysRoleMenuService;
import com.ema.admin.modules.system.vo.SysMenuQueryVo;
import com.ema.admin.modules.system.vo.SysMenuVo;
import com.ema.common.domain.enums.BooleanEnum;
import com.ema.common.utils.TreeUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 菜单权限表 服务层实现。
 *
 * @author LIJIAN
 * @since 2026-03-23
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu>  implements SysMenuService{

    @Resource
    private SysRoleMenuService sysRoleMenuService;
    @Resource
    private SysMenuConverter sysMenuConverter;

    @Override
    public List<SysMenu> getMenuByRoles(List<SysRole> sysRoles) {
        List<String> roleIds = sysRoles.stream().map(SysRole::getId).distinct().collect(Collectors.toList());
        return this.getMenuByRoleIds(roleIds);
    }

    @Override
    public List<SysMenu> getMenuByRoleIds(List<String> roleIds) {
        List<SysRoleMenu> roleMenus = sysRoleMenuService.queryChain()
                .in(SysRoleMenu::getRoleId, roleIds).list();
        if (CollUtil.isEmpty(roleMenus)) {
            return CollUtil.newArrayList();
        }
        List<String> menuIds = roleMenus.stream()
                .map(SysRoleMenu::getMenuId)
                .distinct().collect(Collectors.toList());
        return this.queryChain().in(SysMenu::getId, menuIds)
                .eq(SysMenu::getStatus, BooleanEnum.TRUE.getValue())
                .orderBy(SysMenu::getSort, true).list();
    }

    @Override
    public Page<SysMenu> page(SysMenuQueryVo queryVo) {
        QueryWrapper queryWrapper = QueryWrapper.create();
        queryWrapper.like(SysMenu::getMenuName, queryVo.getMenuName(), StrUtil.isNotBlank(queryVo.getMenuName()));
        queryWrapper.eq(SysMenu::getParentId, queryVo.getParentId(), StrUtil.isNotBlank(queryVo.getParentId()));
        queryWrapper.eq(SysMenu::getMenuType, queryVo.getMenuType(), StrUtil.isNotBlank(queryVo.getMenuType()));
        queryWrapper.eq(SysMenu::getVisible, queryVo.getVisible(), StrUtil.isNotBlank(queryVo.getVisible()));
        queryWrapper.eq(SysMenu::getStatus, queryVo.getStatus(), StrUtil.isNotBlank(queryVo.getStatus()));
        queryWrapper.orderBy(SysMenu::getSort);
        return this.page(new Page<>(queryVo.getPageNumber(), queryVo.getPageSize()), queryWrapper);
    }

    @Override
    public List<SysMenuVo> getTree(String status, String roleId) {
        List<SysMenu> menuList = this.getList(status);
        if (CollUtil.isEmpty(menuList)) return CollUtil.newArrayList();

        List<String> childIds = null;
        if (StrUtil.isNotBlank(roleId)) {
            childIds = sysRoleMenuService.queryChain()
                    .eq(SysRoleMenu::getRoleId, roleId).list()
                    .stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());
        }
        return TreeUtil.buildTree(sysMenuConverter.toSysMenuVo(menuList), childIds);
    }

    @Override
    public List<SysMenu> getList(String status) {
        return this.queryChain()
                .eq(SysMenu::getStatus, status, Objects.nonNull(status))
                .orderBy(SysMenu::getSort).asc().list();
    }
}
