package com.ho.user.controller;


import cn.hutool.core.lang.Snowflake;
import com.ho.common.tools.annotation.LogAnnotation;
import com.ho.common.tools.constant.CommonConstant;
import com.ho.common.tools.constant.ContextConstant;
import com.ho.common.tools.entity.PageVO;
import com.ho.common.tools.entity.SysRole;
import com.ho.common.tools.exception.BaseResponseCode;
import com.ho.common.tools.exception.BusinessException;
import com.ho.common.tools.exception.DataResult;
import com.ho.common.tools.service.RedisService;
import com.ho.user.service.RedisUpdateService;
import com.ho.user.service.RoleService;
import com.ho.user.service.UserRoleService;
import com.ho.user.vo.req.RoleAddReqVO;
import com.ho.user.vo.req.RolePageReqVO;
import com.ho.user.vo.req.RoleUpdateReqVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;


/**
 * Role入口
 */
@RequestMapping(ContextConstant.SYS + "role")
@RestController
@Api(tags = "系统模块-角色管理")
@Slf4j
public class RoleController {

    @Autowired
    private RoleService roleService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    RedisUpdateService redisUpdateService;

    @Autowired
    RedisService redisService;

    @Autowired
    Snowflake snowflake;

    @GetMapping("{id}")
    @ApiOperation(value = "查询角色详情接口")
    //@LogAnnotation(title = "角色管理",action = "查询角色详情")
    //@RequiresPermissions("sys:role:detail")
    public DataResult<SysRole> detailInfo(@PathVariable("id") Integer id) {
        DataResult<SysRole> result = DataResult.success();
        result.setData(roleService.detailInfo(id, null));
        return result;
    }

    @PostMapping("page")
    @ApiOperation(value = "分页获取角色信息接口")
    //@LogAnnotation(title = "角色管理",action = "分页获取角色信息")
    //@RequiresPermissions("sys:role:list")
    public DataResult<PageVO<SysRole>> pageInfo(@RequestBody RolePageReqVO vo) {
        DataResult<PageVO<SysRole>> result = DataResult.success();
        result.setData(roleService.pageInfo(vo));
        return result;
    }

    @PostMapping("list")
    @ApiOperation(value = "获取角色信息接口(不分页)")
    //@LogAnnotation(title = "角色管理",action = "分页获取角色信息")
    //@RequiresPermissions("sys:role:list")
    public DataResult<List<SysRole>> infoList() {
        DataResult<List<SysRole>> result = DataResult.success();
        RolePageReqVO vo = new RolePageReqVO();
        result.setData(roleService.listInfo(vo));
        return result;
    }

    @PostMapping("add")
    @ApiOperation(value = "新增角色接口")
    @LogAnnotation(title = "角色管理", action = "新增角色")
    @RequiresPermissions("sys:role:add")
    public DataResult<SysRole> addRole(@RequestBody @Valid RoleAddReqVO vo) {
        //新增的角色名不能是 超级管理员
        if (CommonConstant.SUPER_ROLE.equals(vo.getName())) {
            throw new BusinessException(BaseResponseCode.ROLE_NAME_CANNOT_BE_SUPER);
        }
        //如果code被赋值了,那么清空
        vo.setCode(null);
        DataResult<SysRole> result = DataResult.success();
        result.setData(roleService.addRole(vo));
        return result;
    }

    @PutMapping("update")
    @ApiOperation(value = "更新角色信息接口")
    @LogAnnotation(title = "角色管理", action = "更新角色信息")
    @RequiresPermissions("sys:role:update")
    public DataResult updateRole(@RequestBody @Valid RoleUpdateReqVO vo, HttpServletRequest request) {

        //超级管理员这个角色不能修改
        SysRole sysRole = roleService.detailInfo(vo.getId(), null);
        if (sysRole == null) {
            throw new BusinessException(BaseResponseCode.DATA_NOT_EXISTS);
        }
        //平台超级管理员不能变更
        if (CommonConstant.SUPER_ROLE_CODE.equals(sysRole.getCode())) {
            throw new BusinessException(BaseResponseCode.SUPER_ROLE_CANNOT_MODIFY);
        }
        //系统内置角色不能操作
        if (sysRole.getCode().startsWith(CommonConstant.SYS_INNER_ROLE_PREFIX)) {
            //throw new BusinessException(BaseResponseCode.INNER_ROLE_CANNOT_MODIFY);
            //内置角色只变更所属菜单
            vo.setName(null);
            vo.setDescription(null);
            vo.setStatus(null);
        }
        //request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN)
        //先修改物理数据
        roleService.updateRole(vo);
        //修改缓存,将这个角色影响的用户缓存做清理,让用户重新登陆获取最新角色列表
        try {
            List<Integer> roleIds = new ArrayList<>();
            roleIds.add(vo.getId());
            redisUpdateService.cleanLoginInfosByRoleId(roleIds);
        } catch (Exception e) {
            log.error("修改角色接口 清除缓存是报错:" + e.getMessage());
        }

        return DataResult.success();
    }

    @DeleteMapping("{id}")
    @ApiOperation(value = "删除角色接口")
    @LogAnnotation(title = "角色管理", action = "删除角色")
    @RequiresPermissions("sys:role:deleted")
    public DataResult deleted(@PathVariable("id") Integer id) {
        //删除角色时要先判断角色是否被使用
        List<Integer> roleIds = new ArrayList<>();
        roleIds.add(id);
        List<String> userIdsByRoleIds = userRoleService.getUserIdsByRoleIds(roleIds);
        if (!userIdsByRoleIds.isEmpty()) {
            throw new BusinessException(BaseResponseCode.ROLE_ALREADY_USED);
        }
        roleService.deletedRole(id);
        //删除缓存 ,捕获一次
        try {
            redisUpdateService.cleanLoginInfosByRoleId(roleIds);
        } catch (Exception e) {
            log.error("删除角色接口 清除缓存是报错:" + e.getMessage());
        }
        return DataResult.success();
    }

}
