package com.haha.admin.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.haha.admin.annotation.RequirePermission;
import com.haha.common.annotation.Log;
import com.haha.common.enums.OperationType;
import com.haha.common.vo.Result;
import com.haha.entity.Menu;
import com.haha.service.MenuService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 菜单管理控制器
 */
@Slf4j
@RestController
@RequestMapping("/menu")
@RequiredArgsConstructor
public class MenuController {

    private final MenuService menuService;

    /**
     * 获取菜单列表（兼容前端 getMenuList 的 POST 请求）
     */
    @RequirePermission("menu:read")
    @PostMapping
    public Result<List<Menu>> list(@RequestBody(required = false) MenuQueryDTO queryDTO) {
        List<Menu> menus;
        if (queryDTO != null && queryDTO.getTitle() != null && !queryDTO.getTitle().isEmpty()) {
            menus = menuService.searchByTitle(queryDTO.getTitle());
        } else {
            menus = menuService.getAllMenus();
        }
        return Result.success(menus);
    }

    /**
     * 创建菜单
     */
    @RequirePermission("menu:create")
    @Log(module = "菜单管理", operation = OperationType.INSERT, summary = "创建菜单")
    @PostMapping("/create")
    public Result<Menu> create(@RequestBody Menu menu) {
        Menu created = menuService.createMenu(menu);
        return Result.success("创建成功", created);
    }

    /**
     * 更新菜单
     */
    @RequirePermission("menu:update")
    @Log(module = "菜单管理", operation = OperationType.UPDATE, summary = "更新菜单")
    @PutMapping("/{id}")
    public Result<Menu> update(@PathVariable Long id, @RequestBody Menu menu) {
        menu.setId(id);
        Menu updated = menuService.updateMenu(menu);
        return Result.success("更新成功", updated);
    }

    /**
     * 删除菜单
     */
    @RequirePermission("menu:delete")
    @Log(module = "菜单管理", operation = OperationType.DELETE, summary = "删除菜单")
    @DeleteMapping("/{id}")
    public Result<Void> delete(@PathVariable Long id) {
        menuService.deleteMenu(id);
        return Result.success("删除成功");
    }

    /**
     * 获取当前用户的菜单树（侧边栏渲染用）
     * 不需要 @RequirePermission，登录用户均可访问
     */
    @GetMapping("/routes")
    public Result<List<Map<String, Object>>> getUserRoutes() {
        // 从 Sa-Token Session 获取用户的角色ID列表
        String roleIdsStr = (String) StpUtil.getSession().get("roleIds");
        List<Long> roleIds = parseRoleIds(roleIdsStr);

        if (roleIds.isEmpty()) {
            return Result.success(List.of());
        }

        List<Map<String, Object>> menuTree = menuService.getUserMenuTree(roleIds);
        return Result.success(menuTree);
    }

    /**
     * 获取全部菜单（角色权限分配用）
     */
    @RequirePermission("role:read")
    @PostMapping("/role-menu")
    public Result<List<Menu>> getRoleMenu() {
        List<Menu> allMenus = menuService.getAllMenus();
        return Result.success(allMenus);
    }

    /**
     * 获取指定角色的菜单ID列表
     */
    @RequirePermission("role:read")
    @PostMapping("/role-menu-ids")
    public Result<List<Long>> getRoleMenuIds(@RequestBody RoleMenuQueryDTO queryDTO) {
        if (queryDTO == null || queryDTO.getId() == null) {
            return Result.success(List.of());
        }
        List<Long> menuIds = menuService.getMenuIdsByRoleId(queryDTO.getId());
        return Result.success(menuIds);
    }

    /**
     * 批量更新菜单排序
     */
    @RequirePermission("menu:update")
    @Log(module = "菜单管理", operation = OperationType.UPDATE, summary = "批量更新菜单排序")
    @PutMapping("/sort")
    public Result<Void> updateSort(@RequestBody List<MenuSortDTO> sortList) {
        List<Menu> menus = sortList.stream().map(dto -> {
            Menu menu = new Menu();
            menu.setId(dto.getId());
            menu.setRank(dto.getRank());
            return menu;
        }).collect(Collectors.toList());
        menuService.updateSort(menus);
        return Result.success("排序更新成功");
    }

    /**
     * 保存角色菜单关联
     */
    @RequirePermission("role:update")
    @Log(module = "菜单管理", operation = OperationType.UPDATE, summary = "保存角色菜单关联")
    @PostMapping("/save-role-menus")
    public Result<Void> saveRoleMenus(@RequestBody SaveRoleMenuDTO dto) {
        if (dto.getRoleId() == null) {
            return Result.error(400, "角色ID不能为空");
        }
        menuService.saveRoleMenus(dto.getRoleId(), dto.getMenuIds());
        return Result.success("保存成功");
    }

    /**
     * 解析角色ID字符串为Long列表
     */
    private List<Long> parseRoleIds(String roleIdsStr) {
        if (roleIdsStr == null || roleIdsStr.trim().isEmpty()) {
            return List.of();
        }
        try {
            return java.util.Arrays.stream(roleIdsStr.split(","))
                    .map(String::trim)
                    .filter(s -> !s.isEmpty())
                    .map(Long::parseLong)
                    .collect(Collectors.toList());
        } catch (NumberFormatException e) {
            log.warn("解析角色ID失败: {}", roleIdsStr, e);
            return List.of();
        }
    }

    // ===== 内部DTO =====

    @lombok.Data
    public static class MenuQueryDTO {
        private String title;
    }

    @lombok.Data
    public static class RoleMenuQueryDTO {
        private Long id;
    }

    @lombok.Data
    public static class MenuSortDTO {
        private Long id;
        private Integer rank;
    }

    @lombok.Data
    public static class SaveRoleMenuDTO {
        private Long roleId;
        private List<Long> menuIds;
    }
}
