package com.starry.admin.modules.system.controller;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.starry.admin.common.domain.TreeSelect;
import com.starry.admin.modules.system.entity.SysMenuEntity;
import com.starry.admin.modules.system.service.SysMenuService;
import com.starry.admin.modules.system.vo.SimpleMenu;
import com.starry.admin.utils.SecurityUtils;
import com.starry.common.constant.UserConstants;
import com.starry.common.result.R;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

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

/**
 * <p>
 * 菜单表 前端控制器
 * </p>
 *
 * @author admin
 * @since 2022-07-03
 */
@RestController
@RequestMapping("/ucenter/menu")
public class SysMenuController {

    @Resource
    private SysMenuService menuService;


    @ApiOperation("获取菜单列表")
    @PreAuthorize("@customSs.hasPermission('system:menu:list')")
    @GetMapping("/list")
    public R list(SysMenuEntity menu) {
        // 获取登录人的userId;
        String userId = SecurityUtils.getUserId();
        List<SysMenuEntity> menus = menuService.selectMenuList(menu, userId);
        return R.ok(menus);
    }

    @ApiOperation("分页获取菜单列表")
    @GetMapping("/list-page")
    public R listPage(@RequestParam(value = "menu", required = false) SysMenuEntity menu,
                      @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize,
                      @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum) {
        Page<SysMenuEntity> pageMenu = menuService.listPage(menu, SecurityUtils.getUserId(), pageSize, pageNum);
        return R.ok(pageMenu);
    }

    @ApiOperation("添加菜单")
    @PreAuthorize("@customSs.hasPermission('system:menu:create')")
    @PostMapping("/create")
    public R create(@RequestBody SysMenuEntity menu) {
        if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu))) {
            return R.error("新增菜单'" + menu.getMenuName() + "'失败，菜单名称已存在");
        } else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StrUtil.startWithAny(menu.getPath(), "http://", "https://")) {
            return R.error("新增菜单'" + menu.getMenuName() + "'失败，地址必须以http(s)://开头");
        }
        boolean success = menuService.create(menu);
        if (success) {
            return R.ok();
        }
        return R.error("添加失败");
    }

    @ApiOperation("修改菜单")
    @PreAuthorize("@customSs.hasPermission('system:menu:edit')")
    @PostMapping("/update/{id}")
    public R update(@PathVariable Long id, @RequestBody SysMenuEntity menu) {
        menu.setMenuId(id);
        if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu))) {
            return R.error("修改菜单'" + menu.getMenuName() + "'失败，菜单名称已存在");
        } else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StrUtil.startWithAny(menu.getPath(), "http://", "https://")) {
            return R.error("修改菜单'" + menu.getMenuName() + "'失败，地址必须以http(s)://开头");
        } else if (menu.getMenuId().equals(menu.getParentId())) {
            return R.error("修改菜单'" + menu.getMenuName() + "'失败，上级菜单不能选择自己");
        }
        boolean success = menuService.updateById(menu);
        if (success) {
            return R.ok();
        }
        return R.error("修改失败");
    }


    @ApiOperation("删除菜单")
    @PreAuthorize("@customSs.hasPermission('system:menu:delete')")
    @PostMapping(value = "/delete/{id}")
    public R delete(@PathVariable("id") Long menuId) {
        if (menuService.hasChildByMenuId(menuId)) {
            return R.error("存在子菜单，不允许删除");
        }
        boolean success = menuService.removeByIds(Collections.singletonList(menuId));
        if (success) {
            return R.ok();
        }
        return R.error("删除失败");
    }

    @ApiOperation("获取菜单下拉树列表")
    @GetMapping("/treeselect")
    public R treeselect(SysMenuEntity menu) {
        List<SysMenuEntity> menus = menuService.selectMenuList(menu, SecurityUtils.getUserId());
        List<TreeSelect> tree = menuService.buildMenuTreeSelect(menus);
        return R.ok(tree);
    }

    @PreAuthorize("@customSs.hasPermission('system:menu:query')")
    @ApiOperation("根据菜单编号获取详细信息")
    @GetMapping(value = "/{menuId}")
    public R getInfo(@PathVariable Long menuId) {
        return R.ok(menuService.selectMenuById(menuId));
    }

    @ApiOperation("获取对应角色菜单列表树")
    @GetMapping(value = "/roleMenuTreeselect/{roleId}")
    public R roleMenuTreeselect(@PathVariable("roleId") Long roleId) {
        List<SysMenuEntity> menus = menuService.selectMenuList(SecurityUtils.getUserId());
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("checkedKeys", menuService.selectMenuListByRoleId(roleId));
        resultMap.put("menus", menuService.buildMenuTreeSelect(menus));
        return R.ok(resultMap);
    }

    @GetMapping("/list-all-simple")
    @ApiOperation(value = "获取菜单精简信息列表", notes = "只包含被开启的菜单，用于【角色分配菜单】功能的选项。" +
            "在多租户的场景下，会只返回租户所在套餐有的菜单")
    public R getSimpleMenus() {
        // 获得菜单列表，只要开启状态的
        List<SimpleMenu> menus = menuService.selectSimpleMenuList();
        // TODO 移除公共模块
        List<Long> forbidList = Arrays.asList(26L, 48L, 47L, 19L);
        List<SimpleMenu> menuList = menus.stream().filter(ca -> !forbidList.contains(ca.getId()) || !forbidList.contains(ca.getParentId())).collect(Collectors.toList());
        return R.ok(menus);
    }
}

