package shop.alien.storeplatform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import shop.alien.entity.store.StorePlatformMenu;
import shop.alien.entity.store.StorePlatformRoleMenu;
import shop.alien.entity.store.vo.RolePermissionTableVo;
import shop.alien.entity.store.vo.RolePermissionVo;
import shop.alien.mapper.StorePlatformMenuMapper;
import shop.alien.mapper.StorePlatformRoleMenuMapper;
import shop.alien.storeplatform.service.StorePlatformRoleMenuService;

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

/**
 * 角色菜单关联表 服务实现类
 *
 * @author system
 * @since 2025-01-XX
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional
public class StorePlatformRoleMenuServiceImpl extends ServiceImpl<StorePlatformRoleMenuMapper, StorePlatformRoleMenu> implements StorePlatformRoleMenuService {

    private final StorePlatformRoleMenuMapper storePlatformRoleMenuMapper;
    private final StorePlatformMenuMapper storePlatformMenuMapper;

    @Override
    public List<Long> getMenuIdsByRoleId(Long roleId) {
        LambdaQueryWrapper<StorePlatformRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StorePlatformRoleMenu::getRoleId, roleId);
        List<StorePlatformRoleMenu> list = storePlatformRoleMenuMapper.selectList(queryWrapper);
        return list.stream().map(StorePlatformRoleMenu::getMenuId).collect(Collectors.toList());
    }

    @Override
    public List<Long> getRoleIdsByMenuId(Long menuId) {
        LambdaQueryWrapper<StorePlatformRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StorePlatformRoleMenu::getMenuId, menuId);
        List<StorePlatformRoleMenu> list = storePlatformRoleMenuMapper.selectList(queryWrapper);
        return list.stream().map(StorePlatformRoleMenu::getRoleId).collect(Collectors.toList());
    }

    @Override
    public boolean assignMenus(Long roleId, List<Long> menuIds) {
        if (roleId == null || menuIds == null || menuIds.isEmpty()) {
            log.error("参数不能为空");
            return false;
        }
        // 先删除角色的所有菜单
        removeAllMenus(roleId);
        // 批量插入新菜单
        List<StorePlatformRoleMenu> roleMenus = menuIds.stream()
                .map(menuId -> {
                    StorePlatformRoleMenu roleMenu = new StorePlatformRoleMenu();
                    roleMenu.setRoleId(roleId);
                    roleMenu.setMenuId(menuId);
                    return roleMenu;
                })
                .collect(Collectors.toList());
        return this.saveBatch(roleMenus);
    }

    @Override
    public boolean removeAllMenus(Long roleId) {
        LambdaQueryWrapper<StorePlatformRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StorePlatformRoleMenu::getRoleId, roleId);
        return storePlatformRoleMenuMapper.delete(queryWrapper) >= 0;
    }

    @Override
    public boolean addMenu(Long roleId, Long menuId) {
        if (roleId == null || menuId == null) {
            log.error("参数不能为空");
            return false;
        }
        // 检查是否已存在
        LambdaQueryWrapper<StorePlatformRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StorePlatformRoleMenu::getRoleId, roleId)
                .eq(StorePlatformRoleMenu::getMenuId, menuId);
        StorePlatformRoleMenu exist = storePlatformRoleMenuMapper.selectOne(queryWrapper);
        if (exist != null) {
            log.warn("角色菜单关联已存在，roleId={}, menuId={}", roleId, menuId);
            return true;
        }
        StorePlatformRoleMenu roleMenu = new StorePlatformRoleMenu();
        roleMenu.setRoleId(roleId);
        roleMenu.setMenuId(menuId);
        return storePlatformRoleMenuMapper.insert(roleMenu) > 0;
    }

    @Override
    public boolean removeMenu(Long roleId, Long menuId) {
        LambdaQueryWrapper<StorePlatformRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StorePlatformRoleMenu::getRoleId, roleId)
                .eq(StorePlatformRoleMenu::getMenuId, menuId);
        return storePlatformRoleMenuMapper.delete(queryWrapper) > 0;
    }

    @Override
    public List<RolePermissionVo> getRolePermissionTree(Long roleId) {
        if (roleId == null) {
            return new ArrayList<>();
        }
        
        // 1. 查询角色拥有的菜单ID列表
        List<Long> menuIds = getMenuIdsByRoleId(roleId);
        if (menuIds == null || menuIds.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 2. 查询这些菜单的详细信息
        LambdaQueryWrapper<StorePlatformMenu> menuQueryWrapper = new LambdaQueryWrapper<>();
        menuQueryWrapper.in(StorePlatformMenu::getMenuId, menuIds);
        menuQueryWrapper.eq(StorePlatformMenu::getDelFlag, "0");
        menuQueryWrapper.eq(StorePlatformMenu::getStatus, "0");
        menuQueryWrapper.orderByAsc(StorePlatformMenu::getMenuSort);
        List<StorePlatformMenu> menus = storePlatformMenuMapper.selectList(menuQueryWrapper);
        
        if (menus == null || menus.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 3. 转换为VO
        List<RolePermissionVo> permissionVos = menus.stream()
                .map(menu -> {
                    RolePermissionVo vo = new RolePermissionVo();
                    BeanUtils.copyProperties(menu, vo);
                    return vo;
                })
                .collect(Collectors.toList());
        
        // 4. 构建树形结构
        return buildPermissionTree(permissionVos);
    }

    /**
     * 构建权限树形结构
     */
    private List<RolePermissionVo> buildPermissionTree(List<RolePermissionVo> flatList) {
        if (flatList == null || flatList.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 创建映射：ID到节点的映射，父ID到子节点列表的映射
        Map<Long, RolePermissionVo> nodeMap = new HashMap<>();
        Map<Long, List<RolePermissionVo>> parentChildMap = new HashMap<>();
        List<RolePermissionVo> result = new ArrayList<>();
        
        // 第一步：建立映射关系
        for (RolePermissionVo vo : flatList) {
            Long menuId = vo.getMenuId();
            Long parentId = vo.getParentId() != null ? vo.getParentId() : 0L;
            
            // 存入节点映射
            nodeMap.put(menuId, vo);
            
            // 如果是根节点（parentId为0或null），直接添加到结果
            if (parentId == null || parentId == 0) {
                result.add(vo);
            } else {
                // 否则，记录父子关系
                parentChildMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(vo);
            }
        }
        
        // 第二步：建立父子关系
        for (RolePermissionVo vo : nodeMap.values()) {
            Long menuId = vo.getMenuId();
            if (parentChildMap.containsKey(menuId)) {
                // 对子节点按排序值排序
                List<RolePermissionVo> children = parentChildMap.get(menuId);
                children.sort(Comparator.comparing(RolePermissionVo::getMenuSort, Comparator.nullsLast(Integer::compareTo)));
                vo.setChildren(children);
            }
        }
        
        // 对根节点按排序值排序
        result.sort(Comparator.comparing(RolePermissionVo::getMenuSort, Comparator.nullsLast(Integer::compareTo)));
        
        return result;
    }

    @Override
    public List<RolePermissionTableVo> getRolePermissionTable(Long roleId) {
        if (roleId == null) {
            return new ArrayList<>();
        }

        // 1. 查询角色拥有的菜单ID列表
        List<Long> menuIds = getMenuIdsByRoleId(roleId);
        if (menuIds == null || menuIds.isEmpty()) {
            return new ArrayList<>();
        }

        // 2. 查询这些菜单的详细信息
        LambdaQueryWrapper<StorePlatformMenu> menuQueryWrapper = new LambdaQueryWrapper<>();
        menuQueryWrapper.in(StorePlatformMenu::getMenuId, menuIds);
        menuQueryWrapper.eq(StorePlatformMenu::getDelFlag, "0");
        menuQueryWrapper.eq(StorePlatformMenu::getStatus, "0");
        menuQueryWrapper.orderByAsc(StorePlatformMenu::getMenuSort);
        List<StorePlatformMenu> menus = storePlatformMenuMapper.selectList(menuQueryWrapper);

        if (menus == null || menus.isEmpty()) {
            return new ArrayList<>();
        }

        // 3. 找出最高层级
        Integer maxLevel = menus.stream()
                .map(StorePlatformMenu::getLevel)
                .filter(Objects::nonNull)
                .max(Integer::compareTo)
                .orElse(1);

        // 4. 如果需要，补充父级权限
        Set<Long> allMenuIds = new HashSet<>(menuIds);
        if (maxLevel >= 3) {
            // 如果有三级权限，需要补充一级和二级父权限
            for (StorePlatformMenu menu : menus) {
                if (menu.getLevel() != null && menu.getLevel() == 3) {
                    // 补充二级父权限
                    if (menu.getParentId() != null && menu.getParentId() != 0) {
                        allMenuIds.add(menu.getParentId());
                        // 补充一级父权限
                        StorePlatformMenu level2Menu = storePlatformMenuMapper.selectById(menu.getParentId());
                        if (level2Menu != null && level2Menu.getParentId() != null && level2Menu.getParentId() != 0) {
                            allMenuIds.add(level2Menu.getParentId());
                        }
                    }
                }
            }
        } else if (maxLevel == 2) {
            // 如果只有二级权限，需要补充一级父权限
            for (StorePlatformMenu menu : menus) {
                if (menu.getLevel() != null && menu.getLevel() == 2) {
                    if (menu.getParentId() != null && menu.getParentId() != 0) {
                        allMenuIds.add(menu.getParentId());
                    }
                }
            }
        }

        // 5. 查询所有需要的菜单（包括补充的父级权限）
        if (allMenuIds.size() > menuIds.size()) {
            LambdaQueryWrapper<StorePlatformMenu> allMenuQueryWrapper = new LambdaQueryWrapper<>();
            allMenuQueryWrapper.in(StorePlatformMenu::getMenuId, allMenuIds);
            allMenuQueryWrapper.eq(StorePlatformMenu::getDelFlag, "0");
            allMenuQueryWrapper.eq(StorePlatformMenu::getStatus, "0");
            allMenuQueryWrapper.orderByAsc(StorePlatformMenu::getMenuSort);
            menus = storePlatformMenuMapper.selectList(allMenuQueryWrapper);
        }

        // 6. 按层级分组
        Map<Integer, List<StorePlatformMenu>> menusByLevel = menus.stream()
                .filter(menu -> menu.getLevel() != null)
                .collect(Collectors.groupingBy(StorePlatformMenu::getLevel));

        // 7. 构建表格数据
        List<RolePermissionTableVo> tableData = new ArrayList<>();

        // 获取一级权限
        List<StorePlatformMenu> level1Menus = menusByLevel.getOrDefault(1, new ArrayList<>());
        level1Menus.sort(Comparator.comparing(StorePlatformMenu::getMenuSort, Comparator.nullsLast(Integer::compareTo)));

        for (StorePlatformMenu level1Menu : level1Menus) {
            // 获取该一级权限下的二级权限
            List<StorePlatformMenu> level2Menus = menusByLevel.getOrDefault(2, new ArrayList<>()).stream()
                    .filter(menu -> level1Menu.getMenuId().equals(menu.getParentId()))
                    .sorted(Comparator.comparing(StorePlatformMenu::getMenuSort, Comparator.nullsLast(Integer::compareTo)))
                    .collect(Collectors.toList());

            if (level2Menus.isEmpty()) {
                // 如果只有一级权限，只显示一级权限
                RolePermissionTableVo vo = new RolePermissionTableVo();
                vo.setLevel1Permission(level1Menu.getMenuName());
                tableData.add(vo);
            } else {
                // 如果有二级权限，遍历二级权限
                for (StorePlatformMenu level2Menu : level2Menus) {
                    // 获取该二级权限下的三级权限
                    List<StorePlatformMenu> level3Menus = menusByLevel.getOrDefault(3, new ArrayList<>()).stream()
                            .filter(menu -> level2Menu.getMenuId().equals(menu.getParentId()))
                            .sorted(Comparator.comparing(StorePlatformMenu::getMenuSort, Comparator.nullsLast(Integer::compareTo)))
                            .collect(Collectors.toList());

                    if (level3Menus.isEmpty()) {
                        // 如果只有二级权限，显示一级和二级权限
                        RolePermissionTableVo vo = new RolePermissionTableVo();
                        vo.setLevel1Permission(level1Menu.getMenuName());
                        vo.setLevel2Permission(level2Menu.getMenuName());
                        tableData.add(vo);
                    } else {
                        // 如果有三级权限，显示一级、二级、三级权限
                        // 将三级权限名称用空格连接
                        String level3PermissionNames = level3Menus.stream()
                                .map(StorePlatformMenu::getMenuName)
                                .collect(Collectors.joining(" "));
                        RolePermissionTableVo vo = new RolePermissionTableVo();
                        vo.setLevel1Permission(level1Menu.getMenuName());
                        vo.setLevel2Permission(level2Menu.getMenuName());
                        vo.setLevel3Permission(level3PermissionNames);
                        tableData.add(vo);
                    }
                }
            }
        }

        return tableData;
    }
}

