package com.ningdatech.carapi.sys.controller;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.validation.Valid;

import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.carapi.datascope.model.DataScopeDto;
import com.ningdatech.carapi.sys.entity.Menu;
import com.ningdatech.carapi.sys.entity.Role;
import com.ningdatech.carapi.sys.entity.RoleMenu;
import com.ningdatech.carapi.sys.entity.dto.RolePageQuery;
import com.ningdatech.carapi.sys.entity.dto.RoleSaveDTO;
import com.ningdatech.carapi.sys.entity.dto.RoleUpdateDTO;
import com.ningdatech.carapi.sys.entity.vo.RoleVO;
import com.ningdatech.carapi.sys.manage.RoleManage;
import com.ningdatech.carapi.sys.service.IRoleMenuService;
import com.ningdatech.carapi.sys.service.MenuService;
import com.ningdatech.carapi.sys.service.RoleService;
import com.ningdatech.carapi.user.security.auth.model.UserInfoDetails;
import com.ningdatech.carapi.user.util.LoginUserUtil;
import com.ningdatech.log.annotation.WebLog;

import cn.hutool.core.bean.BeanUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * 前端控制器
 * 角色
 * </p>
 *
 * @author PoffyZhang
 * @since 2022-09-30
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/api/role")
@Api(value = "Role", tags = "系统管理-角色")
@RequiredArgsConstructor
public class RoleController {
    
    private final RoleService roleService;

    private final RoleManage roleManage;
    private final IRoleMenuService roleMenuService;
    private final MenuService menuService;

    @GetMapping("/test")
    public Optional<DataScopeDto> query() {
        Optional<DataScopeDto> currentUserDataScoper = roleManage.getCurrentUserDataScoper();
        return currentUserDataScoper;
    }

    @ApiOperation(value = "角色列表查询", notes = "角色列表查询")
    @GetMapping("/list")
    public PageVo<RoleVO> query(@Valid @ModelAttribute RolePageQuery rolePageQuery) {
        return roleManage.queryList(rolePageQuery);
    }

    /**
     * 查询角色
     *
     * @param id 主键id
     * @return 查询结果
     */
    @ApiOperation(value = "查询角色", notes = "查询角色")
    @GetMapping("/details")
    public RoleVO getDetails(@Valid @RequestParam Long id) {

        // 判断登录用户是否有角色管理的权限
        if (!checkMenuPower()) {
            return null;
        }

        Role role = roleService.getById(id);
        if (Objects.isNull(role)){
            return null;
        }
        RoleVO query = BeanUtil.toBean(role, RoleVO.class);
        if(Objects.isNull(query)){
            return null;
        }
        //菜单
        roleManage.buildMenu(query);
        return query;
    }

    @ApiOperation(value = "保存新角色", notes = "保存新角色")
    @PostMapping("/save")
    @WebLog(value = "新增角色", modular = "系统管理-角色管理")
    public RoleVO handlerSave(@Valid @RequestBody RoleSaveDTO data) {
        roleService.saveRole(data, LoginUserUtil.getUserId());
        return BeanUtil.toBean(data, RoleVO.class);
    }

    @ApiOperation(value = "编辑角色", notes = "编辑角色")
    @PostMapping("/modify")
    @WebLog(value = "编辑角色", modular = "系统管理-角色管理")
    public RoleVO handlerUpdate(@Valid @RequestBody RoleUpdateDTO data) {
        roleService.updateRole(data, LoginUserUtil.getUserId());
        return BeanUtil.toBean(data, RoleVO.class);
    }

    @ApiOperation(value = "删除角色", notes = "删除角色")
    @PostMapping("/remove")
    @WebLog(value = "删除角色", modular = "系统管理-角色管理")
    public Boolean handlerDelete(@Valid @RequestBody List<Long> ids) {
        // 判断登录用户是否有角色管理的权限
        if (!checkMenuPower()) {
            return false;
        }
        return roleService.removeByIdWithCache(ids);
    }

    private boolean checkMenuPower() {
        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 true;
        }
        if (menuIdList.contains(menu.getId())){
            return true;
        }
        return false;
    }

}
