package shop.alien.store.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import shop.alien.entity.result.R;
import shop.alien.entity.store.LifeSysMenu;
import shop.alien.mapper.LifeSysMenuMapper;
import shop.alien.store.service.LifeSysMenuService;

import java.util.*;

/**
 * 菜单权限表 服务实现类
 *
 * @author system
 * @since 2025-01-XX
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional
public class LifeSysMenuServiceImpl implements LifeSysMenuService {

    private final LifeSysMenuMapper lifeSysMenuMapper;

    @Override
    public R<LifeSysMenu> addMenu(LifeSysMenu menu) {
        log.info("LifeSysMenuServiceImpl.addMenu?menu={}", menu);

        // 参数校验
        if (menu == null) {
            log.warn("新增菜单失败：参数为空");
            return R.fail("参数不能为空");
        }

        // 校验必填字段：菜单名称
        if (!StringUtils.hasText(menu.getMenuName())) {
            return R.fail("菜单名称不能为空");
        }

        // 校验必填字段：菜单类型
        if (!StringUtils.hasText(menu.getMenuType())) {
            return R.fail("菜单类型不能为空");
        }

        // 校验菜单名称是否已存在（同一父菜单下不能有重名）
        QueryWrapper<LifeSysMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("menu_name", menu.getMenuName());
        queryWrapper.eq("del_flag", "0"); // 未删除的菜单
        Long parentId = menu.getParentId() != null ? menu.getParentId() : 0L;
        queryWrapper.eq("parent_id", parentId);
        LifeSysMenu existingMenu = lifeSysMenuMapper.selectOne(queryWrapper);
        if (existingMenu != null) {
            return R.fail("该菜单名称已存在，请更换其他名称");
        }

        // 如果指定了父菜单，校验父菜单是否存在
        if (menu.getParentId() != null && menu.getParentId() != 0) {
            LifeSysMenu parentMenu = lifeSysMenuMapper.selectById(menu.getParentId());
            if (parentMenu == null || !"0".equals(parentMenu.getDelFlag())) {
                return R.fail("父菜单不存在或已被删除");
            }
        }

        // 设置默认值
        if (menu.getParentId() == null) {
            menu.setParentId(0L);
        }
        if (menu.getMenuSort() == null) {
            menu.setMenuSort(0);
        }
        if (!StringUtils.hasText(menu.getStatus())) {
            menu.setStatus("0");
        }
        if (!StringUtils.hasText(menu.getVisible())) {
            menu.setVisible("0");
        }
        if (!StringUtils.hasText(menu.getIsFrame())) {
            menu.setIsFrame("1");
        }
        if (!StringUtils.hasText(menu.getIsCache())) {
            menu.setIsCache("0");
        }
        if (!StringUtils.hasText(menu.getIcon())) {
            menu.setIcon("#");
        }
        menu.setDelFlag("0"); // 未删除

        // 保存菜单
        int result = lifeSysMenuMapper.insert(menu);
        if (result > 0) {
            log.info("新增菜单成功，菜单ID={}", menu.getMenuId());
            return R.data(menu, "新增菜单成功");
        }
        return R.fail("新增菜单失败，请稍后重试");
    }

    @Override
    public R<LifeSysMenu> updateMenu(LifeSysMenu menu) {
        log.info("LifeSysMenuServiceImpl.updateMenu?menu={}", menu);

        // 参数校验
        if (menu == null) {
            log.warn("编辑菜单失败：参数为空");
            return R.fail("参数不能为空");
        }

        // 校验必填字段：菜单ID
        if (menu.getMenuId() == null) {
            return R.fail("菜单ID不能为空");
        }

        // 校验必填字段：菜单名称
        if (!StringUtils.hasText(menu.getMenuName())) {
            return R.fail("菜单名称不能为空");
        }

        // 查询菜单是否存在
        LifeSysMenu existingMenu = lifeSysMenuMapper.selectById(menu.getMenuId());
        if (existingMenu == null) {
            return R.fail("菜单不存在");
        }

        // 检查是否已被删除
        if (!"0".equals(existingMenu.getDelFlag())) {
            return R.fail("该菜单已被删除");
        }

        // 如果菜单名称有变化，校验新名称是否与其他菜单重复（同一父菜单下不能有重名）
        if (!menu.getMenuName().equals(existingMenu.getMenuName())) {
            QueryWrapper<LifeSysMenu> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("menu_name", menu.getMenuName());
            queryWrapper.eq("del_flag", "0"); // 未删除的菜单
            queryWrapper.ne("menu_id", menu.getMenuId()); // 排除当前菜单
            Long parentId = existingMenu.getParentId() != null ? existingMenu.getParentId() : 0L;
            queryWrapper.eq("parent_id", parentId);
            LifeSysMenu duplicateMenu = lifeSysMenuMapper.selectOne(queryWrapper);
            if (duplicateMenu != null) {
                return R.fail("该菜单名称已存在，请更换其他名称");
            }
        }

        // 更新菜单信息
        existingMenu.setMenuName(menu.getMenuName());
        existingMenu.setMenuType(menu.getMenuType());
        existingMenu.setMenuSort(menu.getMenuSort() != null ? menu.getMenuSort() : existingMenu.getMenuSort());
        existingMenu.setPath(menu.getPath());
        existingMenu.setComponent(menu.getComponent());
        existingMenu.setPerms(menu.getPerms());
        existingMenu.setIcon(menu.getIcon() != null ? menu.getIcon() : existingMenu.getIcon());
        existingMenu.setStatus(menu.getStatus() != null ? menu.getStatus() : existingMenu.getStatus());
        existingMenu.setVisible(menu.getVisible() != null ? menu.getVisible() : existingMenu.getVisible());
        existingMenu.setIsFrame(menu.getIsFrame() != null ? menu.getIsFrame() : existingMenu.getIsFrame());
        existingMenu.setIsCache(menu.getIsCache() != null ? menu.getIsCache() : existingMenu.getIsCache());
        existingMenu.setRemark(menu.getRemark());

        // 保存更新
        int result = lifeSysMenuMapper.updateById(existingMenu);
        if (result > 0) {
            log.info("编辑菜单成功，菜单ID={}, 菜单名称={}", existingMenu.getMenuId(), existingMenu.getMenuName());
            return R.data(existingMenu, "编辑菜单成功");
        }
        return R.fail("编辑菜单失败，请稍后重试");
    }

    @Override
    public R<Boolean> deleteMenu(Long menuId) {
        log.info("LifeSysMenuServiceImpl.deleteMenu?menuId={}", menuId);

        // 参数校验
        if (menuId == null) {
            log.warn("删除菜单失败：菜单ID为空");
            return R.fail("菜单ID不能为空");
        }

        // 查询菜单信息
        LifeSysMenu menu = lifeSysMenuMapper.selectById(menuId);
        if (menu == null) {
            return R.fail("菜单不存在");
        }

        // 检查是否已被删除
        if (!"0".equals(menu.getDelFlag())) {
            return R.fail("该菜单已被删除");
        }

        // 检查是否有子菜单（未删除的子菜单）
        QueryWrapper<LifeSysMenu> childQueryWrapper = new QueryWrapper<>();
        childQueryWrapper.eq("parent_id", menuId);
        childQueryWrapper.eq("del_flag", "0"); // 未删除的子菜单
        Integer childCount = lifeSysMenuMapper.selectCount(childQueryWrapper);

        if (childCount != null && childCount > 0) {
            log.warn("删除菜单失败：该菜单下存在{}个子菜单，不允许删除", childCount);
            return R.fail("该菜单下存在子菜单，请先删除子菜单后再删除");
        }

        try {
            // 执行逻辑删除（设置 del_flag = "2"）
            LambdaUpdateWrapper<LifeSysMenu> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(LifeSysMenu::getMenuId, menuId)
                    .set(LifeSysMenu::getDelFlag, "2");

            int result = lifeSysMenuMapper.update(null, updateWrapper);

            if (result > 0) {
                log.info("删除菜单成功，菜单ID={}, 菜单名称={}", menuId, menu.getMenuName());
                return R.success("删除菜单成功");
            } else {
                return R.fail("删除菜单失败");
            }
        } catch (Exception e) {
            log.error("删除菜单失败，菜单ID={}", menuId, e);
            return R.fail("删除菜单失败：" + e.getMessage());
        }
    }

    @Override
    public R<LifeSysMenu> getMenuById(Long menuId) {
        log.info("LifeSysMenuServiceImpl.getMenuById?menuId={}", menuId);

        // 参数校验
        if (menuId == null) {
            log.warn("查询菜单失败：菜单ID为空");
            return R.fail("菜单ID不能为空");
        }

        // 查询菜单
        LifeSysMenu menu = lifeSysMenuMapper.selectById(menuId);
        if (menu == null) {
            return R.fail("菜单不存在");
        }

        // 检查是否已被删除
        if (!"0".equals(menu.getDelFlag())) {
            return R.fail("该菜单已被删除");
        }

        return R.data(menu, "查询成功");
    }

    @Override
    public R<List<LifeSysMenu>> getMenuTree(String menuName) {
        log.info("LifeSysMenuServiceImpl.getMenuTree?menuName={}", menuName);

        try {
            List<LifeSysMenu> allMenus;
            
            if (StringUtils.hasText(menuName)) {
                // 如果有名称查询条件，先查询匹配的菜单
                QueryWrapper<LifeSysMenu> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("del_flag", "0"); // 只查询未删除的菜单
                queryWrapper.like("menu_name", menuName);
                queryWrapper.orderByAsc("menu_sort"); // 按排序值升序排列
                List<LifeSysMenu> matchedMenus = lifeSysMenuMapper.selectList(queryWrapper);

                if (matchedMenus == null || matchedMenus.isEmpty()) {
                    return R.data(new ArrayList<>(), "查询成功");
                }

                // 收集所有匹配菜单的ID
                Set<Long> menuIdSet = new HashSet<>();
                for (LifeSysMenu menu : matchedMenus) {
                    menuIdSet.add(menu.getMenuId());
                }

                // 递归查找所有父级菜单ID，直到根节点
                Set<Long> parentIds = new HashSet<>();
                for (LifeSysMenu menu : matchedMenus) {
                    Long parentId = menu.getParentId();
                    if (parentId != null && parentId != 0) {
                        parentIds.add(parentId);
                    }
                }

                // 递归向上查找所有父级菜单
                while (!parentIds.isEmpty()) {
                    Set<Long> nextLevelParentIds = new HashSet<>();
                    // 批量查询父级菜单
                    QueryWrapper<LifeSysMenu> parentQueryWrapper = new QueryWrapper<>();
                    parentQueryWrapper.eq("del_flag", "0");
                    parentQueryWrapper.in("menu_id", parentIds);
                    List<LifeSysMenu> parentMenus = lifeSysMenuMapper.selectList(parentQueryWrapper);
                    
                    for (LifeSysMenu parentMenu : parentMenus) {
                        Long parentMenuId = parentMenu.getMenuId();
                        if (!menuIdSet.contains(parentMenuId)) {
                            menuIdSet.add(parentMenuId);
                            Long grandParentId = parentMenu.getParentId();
                            if (grandParentId != null && grandParentId != 0) {
                                nextLevelParentIds.add(grandParentId);
                            }
                        }
                    }
                    parentIds = nextLevelParentIds;
                }

                // 一次性查询所有相关的菜单（包括匹配的菜单和父级菜单）
                QueryWrapper<LifeSysMenu> allQueryWrapper = new QueryWrapper<>();
                allQueryWrapper.eq("del_flag", "0");
                allQueryWrapper.in("menu_id", menuIdSet);
                allQueryWrapper.orderByAsc("menu_sort");
                allMenus = lifeSysMenuMapper.selectList(allQueryWrapper);
            } else {
                // 如果没有名称查询条件，查询所有未删除的菜单
                QueryWrapper<LifeSysMenu> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("del_flag", "0"); // 只查询未删除的菜单
                queryWrapper.orderByAsc("menu_sort"); // 按排序值升序排列
                allMenus = lifeSysMenuMapper.selectList(queryWrapper);
            }

            if (allMenus == null || allMenus.isEmpty()) {
                return R.data(new ArrayList<>(), "查询成功");
            }

            // 构建树形结构
            List<LifeSysMenu> treeList = buildMenuTree(allMenus);

            log.info("查询菜单树成功，菜单数量={}", allMenus.size());
            return R.data(treeList, "查询成功");
        } catch (Exception e) {
            log.error("查询菜单树失败", e);
            return R.fail("查询菜单树失败：" + e.getMessage());
        }
    }

    @Override
    public R<List<LifeSysMenu>> getMenuListByParentId(Long parentId) {
        log.info("LifeSysMenuServiceImpl.getMenuListByParentId?parentId={}", parentId);

        try {
            QueryWrapper<LifeSysMenu> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("del_flag", "0"); // 只查询未删除的菜单
            if (parentId != null) {
                queryWrapper.eq("parent_id", parentId);
            } else {
                queryWrapper.eq("parent_id", 0);
            }
            queryWrapper.orderByAsc("menu_sort"); // 按排序值升序排列
            List<LifeSysMenu> menuList = lifeSysMenuMapper.selectList(queryWrapper);

            log.info("查询菜单列表成功，父菜单ID={}, 菜单数量={}", parentId, menuList != null ? menuList.size() : 0);
            return R.data(menuList, "查询成功");
        } catch (Exception e) {
            log.error("查询菜单列表失败，父菜单ID={}", parentId, e);
            return R.fail("查询菜单列表失败：" + e.getMessage());
        }
    }

    @Override
    public R<List<LifeSysMenu>> getMenuByUserId(Long userId, Long ifTree) {
        log.info("LifeSysMenuServiceImpl.getMenuByUserId?userId={}, ifTree={}", userId, ifTree);
        List<LifeSysMenu> menuByUserId = lifeSysMenuMapper.getMenuByUserId(userId);
        if (ifTree == null || ifTree == 0) {
            return R.data(menuByUserId, "查询成功");
        } else {
            return R.data(buildMenuTree(menuByUserId), "查询成功");
        }
    }
    /**
     * 构建菜单树形结构
     *
     * @param flatList 扁平列表
     * @return 树形结构列表
     */
    private List<LifeSysMenu> buildMenuTree(List<LifeSysMenu> flatList) {
        if (flatList == null || flatList.isEmpty()) {
            return new ArrayList<>();
        }

        // 创建映射：ID到节点的映射，父ID到子节点列表的映射
        Map<Long, LifeSysMenu> nodeMap = new HashMap<>();
        Map<Long, List<LifeSysMenu>> parentChildMap = new HashMap<>();
        List<LifeSysMenu> result = new ArrayList<>();

        // 第一步：建立映射关系
        for (LifeSysMenu menu : flatList) {
            Long menuId = menu.getMenuId();
            Long parentId = menu.getParentId() != null ? menu.getParentId() : 0L;
            HashMap<String, Object> metaMap = new HashMap<>();
            metaMap.put("title",menu.getMenuName());
            metaMap.put("isFull","false");
            if (menu.getStatus().equals("1")) {
                metaMap.put("isHide",true);
            } else {
                metaMap.put("isHide",false);
            }
            menu.setMeta(metaMap);
            // 存入节点映射
            nodeMap.put(menuId, menu);

            // 如果是根节点（parentId为0或null），直接添加到结果
            if (parentId == null || parentId == 0) {
                result.add(menu);
            } else {
                // 否则，记录父子关系
                parentChildMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(menu);
            }
        }

        // 第二步：建立父子关系
        for (LifeSysMenu menu : nodeMap.values()) {
            Long menuId = menu.getMenuId();
            if (parentChildMap.containsKey(menuId)) {
                // 对子节点按排序值排序
                List<LifeSysMenu> children = parentChildMap.get(menuId);
                children.sort(Comparator.comparing(LifeSysMenu::getMenuSort, Comparator.nullsLast(Integer::compareTo)));
                menu.setChildren(children);
            }
        }

        // 对根节点按排序值排序
        result.sort(Comparator.comparing(LifeSysMenu::getMenuSort, Comparator.nullsLast(Integer::compareTo)));

        return result;
    }
}

