package com.mosty.common.core.business.controller;


import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mosty.common.base.constant.enums.DeletedEnum;
import com.mosty.common.base.domain.ResponseResult;
import com.mosty.common.base.entity.log.BusinessType;
import com.mosty.common.base.entity.log.Log;
import com.mosty.common.base.entity.log.OperatorType;
import com.mosty.common.base.exception.Asserts;
import com.mosty.common.base.util.IpUtil;
import com.mosty.common.config.entity.vo.DeleteVO;
import com.mosty.common.core.business.entity.*;
import com.mosty.common.core.business.entity.vo.*;
import com.mosty.common.core.business.service.*;
import com.mosty.common.core.config.DefaultRoleConfig;
import com.mosty.common.token.JwtSysUser;
import com.mosty.common.token.UserInfo;
import com.mosty.common.token.UserInfoManager;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

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

/**
 * <p>
 * 角色表 前端控制器
 * </p>
 *
 * @author kevin
 * @since 2022-02-12
 */
@SuppressWarnings("unused")
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/sysRole")
@Api(tags = "角色信息接口")
public class SysRoleController {

    private final SysUserService sysUserService;
    private final SysRoleService sysRoleService;
    private final SysDeptService sysDeptService;
    private final SysUserRoleService sysUserRoleService;
    private final SysRoleDeptService sysRoleDeptService;
    private final DefaultRoleConfig defaultRoleConfig;
    private final LoginService loginService;

    @JwtSysUser
    @PostMapping("addSysRole")
    @Log(title = "角色功能--添加角色", businessType = BusinessType.INSERT)
    @ApiOperation(value = "添加角色", httpMethod = "POST", response = Boolean.class)
    public ResponseResult<Boolean> addSysRole(@RequestBody @Valid AddRoleVO addRoleVo,
                                              HttpServletRequest servletRequest) {
        // 获取ip地址
        String ipAddress = IpUtil.getIpAddress(servletRequest);

        String roleCode = addRoleVo.getRoleCode();
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_code", roleCode);
        queryWrapper.eq("xt_zxbz", DeletedEnum.NATURE.code);
        List<SysRole> list = sysRoleService.list(queryWrapper);
        Asserts.check(CollectionUtils.isNotEmpty(list), "角色编码%s已存在，请修改", roleCode);

        sysRoleService.insertRole(addRoleVo, ipAddress);
        return ResponseResult.success(Boolean.TRUE);
    }

    @JwtSysUser
    @PostMapping("updateSysRole")
    @Log(title = "角色功能--修改角色信息", businessType = BusinessType.UPDATE)
    @ApiOperation(value = "修改角色信息", httpMethod = "POST", response = Boolean.class)
    public ResponseResult<Boolean> updateSysRole(@RequestBody @Valid SysRoleVO sysRoleVO,
                                                 HttpServletRequest servletRequest) {

        Asserts.check(sysRoleVO.getId() == null, "主键id不能为空！");
        SysRole oldSysRole = sysRoleService.getBaseMapper().selectById(sysRoleVO.getId());
        Asserts.check(oldSysRole == null, "主键为 %s 的角色信息不存在", sysRoleVO.getId());

        String roleCode = sysRoleVO.getRoleCode();
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.ne("id", sysRoleVO.getId());
        queryWrapper.eq("role_code", roleCode);
        queryWrapper.eq("xt_zxbz", DeletedEnum.NATURE.code);
        List<SysRole> list = sysRoleService.list(queryWrapper);
        Asserts.check(CollectionUtils.isNotEmpty(list), "角色编码%s已存在，请修改", roleCode);

        // 获取ip地址
        String ipAddress = IpUtil.getIpAddress(servletRequest);

        UserInfo userInfo = UserInfoManager.get();
        oldSysRole.setXtZhxgsj(new Date());
        oldSysRole.setXtZhxgrid(userInfo.getUserId().toString());
        oldSysRole.setXtZhxgrxm(userInfo.getUserName());
        oldSysRole.setXtZhxgrbmid(userInfo.getDeptId().toString());
        oldSysRole.setXtZhxgrbm(userInfo.getDeptName());
        oldSysRole.setXtZhxgip(ipAddress);

        oldSysRole.setRoleName(sysRoleVO.getRoleName());
        oldSysRole.setRoleCode(sysRoleVO.getRoleCode());
        oldSysRole.setRoleDesc(sysRoleVO.getRoleDesc());
        oldSysRole.setBz(sysRoleVO.getBz());
        oldSysRole.setOrderNo(sysRoleVO.getOrderNo());
        oldSysRole.setDataPermissionLevel(sysRoleVO.getDataPermissionLevel());

        sysRoleService.getBaseMapper().updateById(oldSysRole);
        return ResponseResult.success(Boolean.TRUE);
    }

    @JwtSysUser
    @PostMapping("deleteSysRole")
    @Log(title = "角色功能--删除角色信息", businessType = BusinessType.DELETE)
    @ApiOperation(value = "删除角色信息", httpMethod = "POST", response = Boolean.class)
    public ResponseResult<Boolean> deleteSysRole(@RequestBody DeleteVO deleteVO, HttpServletRequest servletRequest) {
        SysRole oldSysRole = sysRoleService.getBaseMapper().selectById(deleteVO.getId());
        Asserts.check(oldSysRole == null, "主键为 %s 的角色信息不存在", deleteVO.getId());

        QueryWrapper<SysUserRole> countUserWrapper = new QueryWrapper<>();
        countUserWrapper.eq("role_id", oldSysRole.getId());
        Integer countUser = sysUserRoleService.getBaseMapper().selectCount(countUserWrapper);
        Asserts.check(countUser > 0, "存在用户角色，请先删除！");

        QueryWrapper<SysRoleDept> countDeptWrapper = new QueryWrapper<>();
        countDeptWrapper.eq("role_id", oldSysRole.getId());
        Integer countDept = sysRoleDeptService.getBaseMapper().selectCount(countDeptWrapper);
        Asserts.check(countDept > 0, "存在部门角色，请先删除！");

        // 默认角色不能进行删除
        defaultRoleConfig.getDefaultRoleList().forEach(roleId ->
                Asserts.check(oldSysRole.getId().equals(roleId), "默认角色不能进行删除！"));

        oldSysRole.setXtZxbz(DeletedEnum.DELETED.code);
        oldSysRole.setXtZxyy(deleteVO.getZxyy());

        // 获取ip地址
        String ipAddress = IpUtil.getIpAddress(servletRequest);

        UserInfo userInfo = UserInfoManager.get();
        oldSysRole.setXtZhxgsj(new Date());
        oldSysRole.setXtZhxgrid(userInfo.getUserId().toString());
        oldSysRole.setXtZhxgrxm(userInfo.getUserName());
        oldSysRole.setXtZhxgrbmid(userInfo.getDeptId().toString());
        oldSysRole.setXtZhxgrbm(userInfo.getDeptName());
        oldSysRole.setXtZhxgip(ipAddress);

        sysRoleService.getBaseMapper().updateById(oldSysRole);
        return ResponseResult.success(Boolean.TRUE);
    }

    @GetMapping("selectUnAccreditPage")
    @ApiOperation(value = "分页查询未绑定当前用户的角色", httpMethod = "GET", response = SysRole.class)
    public ResponseResult<IPage<SysRole>> selectUnAccreditPage(RolePage rolePage) {
        IPage<SysRole> roleIPage = sysRoleService.selectUnAccreditPage(rolePage);
        return ResponseResult.success(roleIPage);
    }

    @JwtSysUser
    @GetMapping("selectPage")
    @ApiOperation(value = "分页查询角色信息", httpMethod = "GET", response = SysRole.class)
    public ResponseResult<IPage<SysRole>> selectPage(RolePage rolePage) {

        IPage<SysRole> roleIPage = sysRoleService.selectByPage(rolePage);
        return ResponseResult.success(roleIPage);
    }

    @JwtSysUser
    @GetMapping("roleUserList")
    @Log(title = "角色功能", businessType = BusinessType.GRANT)
    @ApiOperation(value = "查询角色管理的用户【需要控制当前人的权限】", httpMethod = "GET", response = SysUserVO.class)
    public ResponseResult<IPage<SysUserVO>> roleUserList(RoleUserPage roleUserPage) {
        UserInfo userInfo = UserInfoManager.get();
        SysDept sysDept = sysDeptService.getById(userInfo.getDeptId());
        IPage<SysUserVO> userPage = sysUserRoleService.roleUserList(sysDept.getRootPath(), roleUserPage);
        return ResponseResult.success(userPage);
    }

    @JwtSysUser
    @PostMapping("grantRoleToUser")
    @Log(title = "角色功能--为用户授予角色", businessType = BusinessType.GRANT)
    @ApiOperation(value = "为用户授予角色", httpMethod = "POST", response = Boolean.class)
    public ResponseResult<Boolean> grantRoleToUser(@RequestBody UserRoleVO userRoleVo) {
        UserInfo userInfo = UserInfoManager.get();
        boolean save = sysUserRoleService.grantRoleToUser(userRoleVo);
        return ResponseResult.success(save);
    }

    @PostMapping("grantUserToRole")
    @Log(title = "角色功能--为角色授予用户", businessType = BusinessType.GRANT)
    @ApiOperation(value = "为角色授予用户", httpMethod = "POST", response = Boolean.class)
    public ResponseResult<Boolean> grantUserToRole(@RequestBody RoleUserVO roleUserVO) {
        boolean save = sysUserRoleService.grantUserToRole(roleUserVO);
        return ResponseResult.success(save);
    }

    @JwtSysUser
    @PostMapping("batchUnboundUserRole")
    @Log(title = "角色功能--批量解绑用户角色", businessType = BusinessType.OTHER)
    @ApiOperation(value = "批量解绑用户角色", httpMethod = "POST", response = Boolean.class)
    public ResponseResult<Boolean> batchUnboundUserRole(@RequestBody UnboundUserRoleVO unboundUserRoleVo) {
        QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.and(wrapper -> wrapper.in("id", unboundUserRoleVo.getIds()));
        boolean save = sysUserRoleService.remove(queryWrapper);
        return ResponseResult.success(save);
    }

    @GetMapping("getUserRoleList/{userId}")
    @ApiOperation(value = "查询用户角色列表", httpMethod = "GET", response = SysRoleVO.class)
    public ResponseResult<List<SysRoleVO>> getUserRoleList(@PathVariable Long userId) {
        List<SysRoleVO> userRoleList = sysRoleService.getUserRoleList(userId);
        return ResponseResult.success(userRoleList);
    }


    @GetMapping("getRoleUserList")
    @ApiOperation(value = "查询角色下用户列表", httpMethod = "GET", response = SysRoleVO.class)
    public ResponseResult<IPage<SysUserVO>> getRoleUserList(GetUserRoleListVo vo) {
        IPage<SysUserVO> deptIPage = sysRoleService.getRoleUserList(vo);
        return ResponseResult.success(deptIPage);

    }

    @PostMapping("saveRoleMenuInfo")
    @JwtSysUser
    @Log(title = "角色功能--添加角色菜单关联关系", businessType = BusinessType.GRANT)
    @ApiOperation(value = "添加角色菜单关联关系", httpMethod = "POST", response = Boolean.class)
    public ResponseResult<Boolean> saveRoleMenuInfo(@RequestBody AddRoleMenuVO roleMenuVO) {
        log.info("添加角色菜单关联关系 roleMenuVO={}", JSON.toJSONString(roleMenuVO));

        SysRole sysRole = sysRoleService.getById(roleMenuVO.getRoleId());
        Asserts.check(sysRole == null || DeletedEnum.DELETED.code.equals(sysRole.getXtZxbz()),
                "角色id不存在或已删除");

        sysRoleService.saveRoleMenuInfo(roleMenuVO);
        return ResponseResult.success(Boolean.TRUE);
    }

    @PostMapping("saveDataPermission")
    @JwtSysUser
    @Log(title = "角色功能", businessType = BusinessType.GRANT)
    @ApiOperation(value = "添加数据权限", httpMethod = "POST", response = Boolean.class)
    public ResponseResult<Boolean> saveDataPermission(@RequestBody AddRoleDataPartitionVO addRoleDataPartitionVO, HttpServletRequest servletRequest) {
        String ipAddress = IpUtil.getIpAddress(servletRequest);
        sysRoleService.saveDataPermission(addRoleDataPartitionVO, ipAddress);
        return ResponseResult.success(Boolean.TRUE);
    }

    /**
     * 根据菜单标识查询数据权限
     *
     * @param menuUrl 菜单URL
     * @return 删除结果
     */
    @PostMapping("getDataPermission/{menuUrl}")
    @ApiOperation(value = "根据菜单标识查询数据权限", httpMethod = "GET", response = Boolean.class)
    public ResponseResult<DataPermissionVO> getDataPermission(@PathVariable("menuUrl") String menuUrl) {
        DataPermissionVO dataPermissionVO = sysRoleService.getDataPermission(menuUrl);
        return ResponseResult.success(dataPermissionVO);
    }

    @GetMapping("getRoleMenuIds/{roleId}")
    @ApiOperation(value = "查询用户绑定的菜单ids", httpMethod = "GET", response = SysRoleVO.class)
    public ResponseResult<List<Long>> getRoleMenuIds(@PathVariable Long roleId) {
        List<Long> menuIds = sysRoleService.getRoleMenuIds(roleId);
        return ResponseResult.success(menuIds);

    }


}

