package com.aiotagro.cattletrade.business.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import com.aiotagro.cattletrade.business.entity.SysMenu;
import com.aiotagro.cattletrade.business.entity.SysRoleMenu;
import com.aiotagro.cattletrade.business.mapper.SysMenuMapper;
import com.aiotagro.cattletrade.business.mapper.SysRoleMenuMapper;
import com.aiotagro.common.core.web.domain.AjaxResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 菜单权限管理控制器
 *
 * @author System
 * @date 2025-10-11
 */
@Slf4j
@RestController
@RequestMapping("/sysMenu")
public class SysMenuController {

    @Resource
    private SysMenuMapper sysMenuMapper;

    @Resource
    private SysRoleMenuMapper sysRoleMenuMapper;

    /**
     * 获取菜单树（所有菜单）
     */
    @SaCheckPermission("permission:menu:list")
    @GetMapping("/tree")
    public AjaxResult getMenuTree() {
        List<SysMenu> allMenus = sysMenuMapper.selectList(
            new LambdaQueryWrapper<SysMenu>()
                .eq(SysMenu::getIsDelete, 0)
                .orderByAsc(SysMenu::getSort)
        );
        
        List<Map<String, Object>> tree = buildMenuTree(allMenus, 0);
        return AjaxResult.success(tree);
    }

    /**
     * 获取菜单列表（扁平）
     */
    @SaCheckPermission("permission:menu:list")
    @GetMapping("/list")
    public AjaxResult getMenuList() {
        List<SysMenu> menus = sysMenuMapper.selectList(
            new LambdaQueryWrapper<SysMenu>()
                .eq(SysMenu::getIsDelete, 0)
                .orderByAsc(SysMenu::getSort)
        );
        return AjaxResult.success(menus);
    }

    /**
     * 根据角色ID获取菜单列表（用于角色权限分配）
     */
    @SaCheckPermission("permission:menu:list")
    @GetMapping("/listByRoleId")
    public AjaxResult getMenuListByRoleId(@RequestParam Integer roleId) {
        List<SysMenu> menus = sysMenuMapper.queryListByRoleId(roleId);
        return AjaxResult.success(menus);
    }

    /**
     * 获取角色已分配的菜单ID列表
     */
    @SaCheckPermission("permission:menu:list")
    @GetMapping("/roleMenuIds")
    public AjaxResult getRoleMenuIds(@RequestParam Integer roleId) {
        log.info("=== 获取角色菜单权限 === roleId: {}", roleId);
        
        List<SysRoleMenu> roleMenus = sysRoleMenuMapper.selectList(
            new LambdaQueryWrapper<SysRoleMenu>()
                .eq(SysRoleMenu::getRoleId, roleId)
        );
        
        log.info("=== 查询到的角色菜单关联记录数: {}", roleMenus.size());
        
        List<Integer> menuIds = roleMenus.stream()
            .map(SysRoleMenu::getMenuId)
            .collect(Collectors.toList());
        
        log.info("=== 返回的菜单ID列表: {}", menuIds);
        
        return AjaxResult.success(menuIds);
    }

    /**
     * 新增菜单
     */
    @SaCheckPermission("permission:menu:add")
    @PostMapping("/add")
    public AjaxResult addMenu(@RequestBody SysMenu menu) {
        menu.setIsDelete(0);
        menu.setCreateTime(new Date());
        int result = sysMenuMapper.insert(menu);
        return result > 0 ? AjaxResult.success("添加成功") : AjaxResult.error("添加失败");
    }

    /**
     * 更新菜单
     */
    @SaCheckPermission("permission:menu:edit")
    @PostMapping("/update")
    public AjaxResult updateMenu(@RequestBody SysMenu menu) {
        menu.setUpdateTime(new Date());
        int result = sysMenuMapper.updateById(menu);
        return result > 0 ? AjaxResult.success("更新成功") : AjaxResult.error("更新失败");
    }

    /**
     * 删除菜单（软删除）
     */
    @SaCheckPermission("permission:menu:delete")
    @GetMapping("/delete")
    public AjaxResult deleteMenu(@RequestParam Integer id) {
        SysMenu menu = new SysMenu();
        menu.setId(id);
        menu.setIsDelete(1);
        menu.setUpdateTime(new Date());
        int result = sysMenuMapper.updateById(menu);
        return result > 0 ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
    }

    /**
     * 为角色分配菜单权限
     */
    @SaCheckPermission("permission:menu:assign")
    @PostMapping("/assignRoleMenus")
    public AjaxResult assignRoleMenus(@RequestBody Map<String, Object> params) {
        Integer roleId = (Integer) params.get("roleId");
        @SuppressWarnings("unchecked")
        List<Integer> menuIds = (List<Integer>) params.get("menuIds");
        
        log.info("=== 分配角色菜单权限 ===");
        log.info("roleId: {}", roleId);
        log.info("menuIds: {}", menuIds);
        
        if (roleId == null) {
            log.error("角色ID不能为空");
            return AjaxResult.error("角色ID不能为空");
        }
        
        // 删除原有权限
        int deletedCount = sysRoleMenuMapper.delete(
            new LambdaQueryWrapper<SysRoleMenu>()
                .eq(SysRoleMenu::getRoleId, roleId)
        );
        log.info("=== 删除原有权限记录数: {}", deletedCount);
        
        // 添加新权限
        if (menuIds != null && !menuIds.isEmpty()) {
            for (Integer menuId : menuIds) {
                SysRoleMenu roleMenu = new SysRoleMenu();
                roleMenu.setRoleId(roleId);
                roleMenu.setMenuId(menuId);
                int insertResult = sysRoleMenuMapper.insert(roleMenu);
                log.info("=== 插入权限记录 menuId: {}, 结果: {}", menuId, insertResult);
            }
            log.info("=== 成功分配 {} 个权限", menuIds.size());
        } else {
            log.info("=== 没有要分配的权限，清空所有权限");
        }
        
        return AjaxResult.success("分配成功");
    }

    /**
     * 构建菜单树
     */
    private List<Map<String, Object>> buildMenuTree(List<SysMenu> menus, Integer parentId) {
        List<Map<String, Object>> tree = new ArrayList<>();
        
        for (SysMenu menu : menus) {
            if (menu.getParentId() != null && menu.getParentId().equals(parentId)) {
                Map<String, Object> node = new HashMap<>();
                node.put("id", menu.getId());
                node.put("label", menu.getName());
                node.put("parentId", menu.getParentId());
                node.put("type", menu.getType());
                node.put("icon", menu.getIcon());
                node.put("sort", menu.getSort());
                node.put("routeUrl", menu.getRouteUrl());
                node.put("pageUrl", menu.getPageUrl());
                node.put("authority", menu.getAuthority());
                
                List<Map<String, Object>> children = buildMenuTree(menus, menu.getId());
                if (!children.isEmpty()) {
                    node.put("children", children);
                }
                
                tree.add(node);
            }
        }
        
        return tree;
    }
}

