package com.cf.imes.module.system.controller.admin.permission;

import cn.hutool.core.collection.CollUtil;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.organ.core.context.OrganContextHolder;
import com.cf.imes.framework.security.core.LoginUser;
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
import com.cf.imes.module.system.controller.admin.permission.vo.permission.PermissionAssignRoleDataScopeReqVO;
import com.cf.imes.module.system.controller.admin.permission.vo.permission.PermissionAssignRoleMenuReqVO;
import com.cf.imes.module.system.controller.admin.permission.vo.permission.PermissionAssignRoleUserReqVO;
import com.cf.imes.module.system.controller.admin.permission.vo.permission.PermissionAssignUserRoleReqVO;
import com.cf.imes.module.system.service.permission.PermissionService;
import com.cf.imes.module.system.service.organ.OrganService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Objects;
import java.util.Set;

import static com.cf.imes.framework.common.pojo.CommonResult.success;
import static com.cf.imes.module.system.service.organ.OrganServiceImpl.ORGAN_ADMIN_ROLE_ID;
import static com.cf.imes.module.system.service.organ.OrganServiceImpl.ORGAN_STAFF_ROLE_ID;

/**
 * 权限 Controller，提供赋予用户、角色的权限的 API 接口
 *
 * @author 晨丰科技
 */
@Tag(name = "管理后台 - 权限")
@RestController
@RequestMapping("/system/permission")
public class PermissionController {

    @Resource
    private PermissionService permissionService;
    @Resource
    private OrganService organService;

    @Operation(summary = "获得角色拥有的菜单编号")
    @Parameter(name = "roleId", description = "角色编号", required = true)
    @GetMapping("/list-role-menus")
    @PreAuthorize("@ss.hasPermission('system:permission:assign-role-menu')")
    public CommonResult<Set<Long>> getRoleMenuList(Long roleId) {
        return success(permissionService.getRoleMenuListByRoleId(roleId));
    }

    @PostMapping("/assign-role-menu")
    @Operation(summary = "赋予角色菜单")
    @PreAuthorize("@ss.hasPermission('system:permission:assign-role-menu')")
    public CommonResult<Boolean> assignRoleMenu(@Validated @RequestBody PermissionAssignRoleMenuReqVO reqVO) {
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        if(!loginUser.getIsSupAdmin() && ( Objects.equals(reqVO.getRoleId(), ORGAN_ADMIN_ROLE_ID) || Objects.equals(reqVO.getRoleId(), ORGAN_STAFF_ROLE_ID))) {
            throw new ServiceException(11541, "内置角色无权修改菜单权限");
        }
        if(Objects.equals(reqVO.getRoleId(), 1L)) {
            throw new ServiceException(11541, "内置角色无权修改菜单权限");
        }
        Set<Long> roleIds = permissionService.getUserRoleIdListByUserId(loginUser.getId());
        if (roleIds.contains(reqVO.getRoleId())) {
            throw new ServiceException(11541, "无法修改自身的角色菜单权限");
        }

        if(Objects.equals(reqVO.getRoleId(), ORGAN_ADMIN_ROLE_ID) || Objects.equals(reqVO.getRoleId(), ORGAN_STAFF_ROLE_ID)) {
        } else {
            // 开启多组织的情况下，需要过滤掉未开通的菜单
            organService.handleOrganMenu(menuIds -> {
                reqVO.getMenuIds().removeIf(menuId -> !CollUtil.contains(menuIds, menuId));
            });
        }
        Long organId = reqVO.getOrganId() == null? OrganContextHolder.getOrganId(): reqVO.getOrganId();
        // 执行菜单的分配
        permissionService.assignRoleMenu(reqVO.getRoleId(), reqVO.getMenuIds(), organId);
        return success(true);
    }

    @PostMapping("/assign-role-data-scope")
    @Operation(summary = "赋予角色数据权限")
    @PreAuthorize("@ss.hasPermission('system:permission:assign-role-data-scope')")
    public CommonResult<Boolean> assignRoleDataScope(@Valid @RequestBody PermissionAssignRoleDataScopeReqVO reqVO) {
        permissionService.assignRoleDataScope(reqVO.getRoleId(), reqVO.getDataScope(), reqVO.getDataScopeDeptIds());
        return success(true);
    }

    @Operation(summary = "获得管理员拥有的角色编号列表")
    @Parameter(name = "userId", description = "用户编号", required = true)
    @GetMapping("/list-user-roles")
    @PreAuthorize("@ss.hasPermission('system:permission:assign-user-role')")
    public CommonResult<Set<Long>> listAdminRoles(@RequestParam("userId") Long userId) {
        return success(permissionService.getUserRoleIdListByUserId(userId));
    }

    @Operation(summary = "赋予用户角色")
    @PostMapping("/assign-user-role")
    @PreAuthorize("@ss.hasPermission('system:permission:assign-user-role')")
    public CommonResult<Boolean> assignUserRole(@Validated @RequestBody PermissionAssignUserRoleReqVO reqVO) {
        Long organId = reqVO.getOrganId() == null ? OrganContextHolder.getOrganId() : reqVO.getOrganId();
        permissionService.assignUserRole(reqVO.getUserId(), reqVO.getRoleIds(), organId);
        return success(true);
    }

    @Operation(summary = "赋予多用户角色")
    @PostMapping("/bath-assign-user-role")
    @PreAuthorize("@ss.hasPermission('system:permission:assign-user-role')")
    public CommonResult<Boolean> bathAssignUserRole(@Validated @RequestBody PermissionAssignRoleUserReqVO reqVO) {
//        permissionService.batchAssignRoleUsers(reqVO);
        return success(true);
    }


    @Operation(summary = "获得拥有角色的用户列表")
    @Parameter(name = "roleId", description = "角色id", required = true)
    @GetMapping("/list-role-users")
    @PreAuthorize("@ss.hasPermission('system:permission:assign-user-role')")
    public CommonResult<Set<Long>> listRoleUsers(@RequestParam("roleId") Long roleId, @RequestParam(value = "organId", required = false) Long organId) {
        return success(permissionService.getListRoleUsers(roleId, organId));
    }

}
