package cn.reghao.oss.console.account.controller;

import cn.reghao.oss.console.account.db.query.MenuQuery;
import cn.reghao.oss.console.account.model.po.Menu;
import cn.reghao.oss.console.account.model.po.Role;
import cn.reghao.oss.console.account.service.RoleService;
import cn.reghao.jutil.jdk.result.WebResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

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

/**
 * @author reghao
 * @date 2021-04-04 21:24:18
 */
@Api(tags = "角色接口")
@RequestMapping("/api/rbac/role")
@RestController
public class RoleController {
    private final MenuQuery menuQuery;
    private final RoleService roleService;

    public RoleController(MenuQuery menuQuery, RoleService roleService) {
        this.menuQuery = menuQuery;
        this.roleService = roleService;
    }

    @ApiOperation("添加或修改角色")
    @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE)
    public String addOrModifyRole(@Validated Role role) {
        roleService.addOrModify(role);
        return WebResult.success();
    }

    @ApiOperation("删除角色")
    @DeleteMapping(value = "/{roleId}", produces = MediaType.APPLICATION_JSON_VALUE)
    public String deleteRole(@PathVariable("roleId") Integer roleId) {
        roleService.delete(roleId);
        return WebResult.success();
    }

    @ApiOperation("获取角色可访问的资源")
    @GetMapping(value = "/menus/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
    public String getRoleMenus(@PathVariable("id") int roleId) {
        Role role = roleService.getRole(roleId);
        List<Menu> allMenus = menuQuery.findAll();
        allMenus.forEach(menu -> {
            // TODO 序列化时会递归 roles 中的 Role 导致 StackOverflow, 因此在序列化时应该把 Role 的 menus 设置为 null
            Set<Role> roles = menu.getRoles().stream()
                    .peek(role1 -> role1.setMenus(null))
                    .collect(Collectors.toSet());
            if (roles.contains(role)) {
                // 对应前端的 checked 复选框
                menu.setRemark("auth:true");
            }
        });

        return WebResult.success(allMenus);
    }

    @ApiOperation("设置角色可访问的资源")
    @PostMapping(value = "/menus", produces = MediaType.APPLICATION_JSON_VALUE)
    public String setRoleMenus(@RequestParam(value = "id") Integer roleId,
                               @RequestParam(value = "menuId") List<Integer> menuIds) {
        Set<Menu> menus = menuQuery.getMenus(menuIds);
        roleService.setRoleMenus(roleId, menus);
        return WebResult.success();
    }
}
