package com.ningdatech.carapi.sys.controller;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.carapi.sys.entity.Menu;
import com.ningdatech.carapi.sys.entity.RoleMenu;
import com.ningdatech.carapi.sys.entity.dto.MenuQueryDTO;
import com.ningdatech.carapi.sys.entity.dto.MenuSaveDTO;
import com.ningdatech.carapi.sys.entity.dto.MenuUpdateDTO;
import com.ningdatech.carapi.sys.entity.vo.MenuRoleVO;
import com.ningdatech.carapi.sys.entity.vo.MenuVO;
import com.ningdatech.carapi.sys.manage.MenuManage;
import com.ningdatech.carapi.sys.service.IRoleMenuService;
import com.ningdatech.carapi.sys.service.MenuService;
import com.ningdatech.carapi.sys.utils.TreeUtil;
import com.ningdatech.carapi.user.security.auth.model.UserInfoDetails;
import com.ningdatech.carapi.user.util.LoginUserUtil;
import com.ningdatech.log.annotation.WebLog;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * 菜单
 * </p>
 *
 * @author PoffyZhang
 * @since 2022-09-30
 */
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/menu")
@Api(value = "Menu", tags = "系统管理-菜单")
public class MenuController {

    private final MenuService menuService;
    private final MenuManage menuManage;
    private final IRoleMenuService roleMenuService;

    /**
     * 查询系统中所有的的菜单树结构， 不用缓存，因为该接口很少会使用，就算使用，也会管理员维护菜单时使用
     */
    @ApiOperation(value = "查询系统所有的菜单", notes = "查询系统所有的菜单")
    @GetMapping("/list")
    public List<Menu> allTree(@Valid @RequestParam(required = false,value = "title") String title) {
        List<Menu> list = menuService.list(Wrappers.lambdaQuery(Menu.class).orderByAsc(Menu::getSort));
        return TreeUtil.buildTree(list,title);
    }

    @ApiOperation(value = "查询当前登录用户的菜单", notes = "查询当前登录用户的菜单")
    @GetMapping("/current_user_menu")
    public List<MenuRoleVO> currentUserMenu() {
        List<Menu> list = menuService.list(Wrappers.lambdaQuery(Menu.class).orderByAsc(Menu::getSort));
        return menuManage.buildUserMenu(list, LoginUserUtil.loginUserDetail());
    }

    /**
     * 查询某个菜单
     *
     * @param id 主键id
     * @return 查询结果
     */
    @ApiOperation(value = "查询菜单", notes = "查询菜单")
    @GetMapping("/details")
    public MenuQueryDTO getDetails(@RequestParam Long id) {
        Menu menu = menuService.getById(id);
        MenuQueryDTO query = BeanUtil.toBean(menu, MenuQueryDTO.class);
        return query;
    }

    @ApiOperation(value = "保存新菜单", notes = "保存新菜单")
    @PostMapping("/save")
    @WebLog(value = "新增菜单", modular = "系统管理-菜单管理")
    public MenuVO handlerSave(@RequestBody MenuSaveDTO data) {
        menuService.save(data, LoginUserUtil.getUserId());
        return BeanUtil.toBean(data, MenuVO.class);
    }

    @ApiOperation(value = "编辑菜单", notes = "编辑菜单")
    @PostMapping("/modify")
    @WebLog(value = "编辑菜单", modular = "系统管理-菜单管理")
    public MenuVO handlerUpdate(@RequestBody MenuUpdateDTO data) {
        menuService.update(data, LoginUserUtil.getUserId());
        return BeanUtil.toBean(data, MenuVO.class);
    }

    @ApiOperation(value = "删除菜单", notes = "删除菜单")
    @PostMapping("/remove")
    @WebLog(value = "删除菜单", modular = "系统管理-菜单管理")
    public Boolean handlerDelete(@RequestBody List<Long> ids) {
        // 判断登录用户是否有菜单管理的权限
        UserInfoDetails userInfoDetails = LoginUserUtil.loginUserDetail();
        Long roleId = userInfoDetails.getRoleId();
        List<Long> menuIdList = roleMenuService.list(Wrappers.lambdaQuery(RoleMenu.class).eq(RoleMenu::getRoleId, roleId)).stream().map(RoleMenu::getMenuId).collect(Collectors.toList());
        Menu menu = menuService.getOne(Wrappers.lambdaQuery(Menu.class).eq(Menu::getTitle, "菜单管理"));
        if (Objects.isNull(menu)){
            return false;
        }
        if (!menuIdList.contains(menu.getId())){
            return false;
        }
        return menuService.removeByIdWithCache(ids);
    }
}
