package cn.skcks.matrix.v2.api.role;

import cn.skcks.matrix.v2.annotation.web.JsonMapping;
import cn.skcks.matrix.v2.annotation.web.auth.Auth;
import cn.skcks.matrix.v2.annotation.web.methods.DeleteJson;
import cn.skcks.matrix.v2.annotation.web.methods.GetJson;
import cn.skcks.matrix.v2.annotation.web.methods.PostJson;
import cn.skcks.matrix.v2.annotation.web.methods.PutJson;
import cn.skcks.matrix.v2.config.swagger.SwaggerConfig;
import cn.skcks.matrix.v2.model.role.convert.RoleConvertor;
import cn.skcks.matrix.v2.model.role.dto.*;
import cn.skcks.matrix.v2.model.role.vo.RoleVo;
import cn.skcks.matrix.v2.model.services.ServiceResult;
import cn.skcks.matrix.v2.model.user.convert.UserConvertor;
import cn.skcks.matrix.v2.model.user.vo.UserVo;
import cn.skcks.matrix.v2.orm.mybatis.dynamic.model.Role;
import cn.skcks.matrix.v2.services.casbin.CasbinService;
import cn.skcks.matrix.v2.services.casbin.Permission;
import cn.skcks.matrix.v2.services.role.RoleService;
import cn.skcks.matrix.v2.utils.json.JsonResponse;
import cn.skcks.matrix.v2.utils.page.PageWrapper;
import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springdoc.core.annotations.ParameterObject;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@Auth
@Tag(name = "角色")
@RestController
@JsonMapping("/role")
@RequiredArgsConstructor
public class RoleController {
    private final RoleService roleService;
    private final CasbinService casbinService;

    @Bean
    public GroupedOpenApi roleApi() {
        return SwaggerConfig.api("Role", "/role");
    }

    @Operation(summary = "添加角色")
    @PutJson("/add")
    public JsonResponse<Void> addRole(@RequestBody @Validated AddRoleParams params) throws Exception {
        ServiceResult<Void> result = roleService.addRole(params.getRoleName(), params.getRole(), params.getSystem(), params.getPermissions());
        return result.parseResponse();
    }

    @Operation(summary = "删除角色")
    @DeleteJson("/del")
    public JsonResponse<Void> delRole(@RequestBody @Validated DelRoleParams params) throws Exception {
        ServiceResult<Void> result = roleService.delRole(params.getRole(), params.getSystem());
        return result.parseResponse();
    }

    @Operation(summary = "查询角色表")
    @PostJson("/list")
    public JsonResponse<PageWrapper<RoleVo>> roles(@RequestBody @Validated GetRoleParams params) {
        PageInfo<Role> roles = roleService.getRoles(params.getPage(), params.getSize(), false);
        return JsonResponse.success(PageWrapper.of(RoleConvertor.INSTANCE.daoToVo(roles)));
    }

    @Operation(summary = "查询角色表(所有)")
    @GetJson("/list/all")
    public JsonResponse<List<RoleVo>> roles() {
        PageInfo<Role> roles = roleService.getRoles(0, 0, true);
        return JsonResponse.success(RoleConvertor.INSTANCE.daoToVo(roles).getList());
    }

    @PostJson("/user/grant")
    @Operation(summary = "授予用户角色")
    public JsonResponse<Boolean> grantRoleForUser(@RequestBody @Validated GrantAndRevokeRoleForUserDto dto) {
        try {
            roleService.grantRoleForUser(dto.getUserId(), dto.getRole(), dto.getSystem());
            return JsonResponse.success(true);
        } catch (Exception e) {
            return JsonResponse.error(false, e.getMessage());
        }
    }

    @DeleteJson("/user/revoke")
    @Operation(summary = "撤销用户角色")
    public JsonResponse<Boolean> revokeRoleForUser(@RequestBody @Validated GrantAndRevokeRoleForUserDto dto) {
        try {
            roleService.revokeRoleForUser(dto.getUserId(), dto.getRole(), dto.getSystem());
            return JsonResponse.success(true);
        } catch (Exception e) {
            return JsonResponse.error(false, e.getMessage());
        }
    }


    @GetJson("/user/roles")
    @Operation(summary = "获取用户所拥有的角色列表")
    public JsonResponse<List<String>> getUserRoles(@ParameterObject @Validated GetUserRoles dto) {
        return JsonResponse.success(roleService.getUserRoles(dto.getUserId(), dto.getSystem()));
    }

    @GetJson("/user/list")
    @Operation(summary = "获取角色下所有的用户列表")
    public JsonResponse<List<UserVo>> getRoleUsers(@ParameterObject @Validated GetRoleUsers dto) {
        List<UserVo> vos = roleService.getRoleUsers(dto.getRole(), dto.getSystem())
                .parallelStream()
                .map(UserConvertor.INSTANCE::daoToVo)
                .toList();
        return JsonResponse.success(vos);
    }

    @GetJson("/user/permissions")
    @Operation(summary = "用户在某个系统下所拥有的权限列表")
    public JsonResponse<List<Permission>> getUserPermissions(@ParameterObject @Validated GetUserPermissions dto) {
        return JsonResponse.success(casbinService.getUserPermission(dto.getUserId(), dto.getSystem()));
    }
}
