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

import cn.skcks.matrix.v2.annotation.web.JsonMapping;
import cn.skcks.matrix.v2.annotation.web.methods.PostJson;
import cn.skcks.matrix.v2.config.swagger.SwaggerConfig;
import cn.skcks.matrix.v2.model.auth.dto.UserLoginDto;
import cn.skcks.matrix.v2.model.auth.dto.UserRegisterDto;
import cn.skcks.matrix.v2.model.auth.vo.UserLoginVo;
import cn.skcks.matrix.v2.model.auth.vo.UserRegisterVo;
import cn.skcks.matrix.v2.model.route.dto.RouteInfo;
import cn.skcks.matrix.v2.services.auth.AuthService;
import cn.skcks.matrix.v2.services.casbin.CasbinRegister;
import cn.skcks.matrix.v2.services.role.RoleService;
import cn.skcks.matrix.v2.utils.json.JsonResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.casbin.jcasbin.main.Enforcer;
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;
import java.util.regex.Pattern;

import static cn.skcks.matrix.v2.services.casbin.CasbinService.DEFAULT_SYSTEM;

@Tag(name = "用户认证")
@RestController
@JsonMapping("/auth")
@RequiredArgsConstructor
public class AuthController implements CasbinRegister {
    private final AuthService authService;

    public final static String LOGIN_PERMISSION = "login";
    public final static String LOGIN_PERMISSION_NAME = "登录";

    @Bean
    public GroupedOpenApi authApi() {
        return SwaggerConfig.api("Auth", "/auth");
    }

    @Override
    public void register(Enforcer enforcer, List<RouteInfo> routes, RoleService roleService) {
        log.info("[casbin] 初始化 {} 权限", LOGIN_PERMISSION_NAME);
        roleService.initRole(LOGIN_PERMISSION, LOGIN_PERMISSION_NAME, true);

        List<RouteInfo> filterRoutes = routes.stream()
                .filter(routeInfo -> Pattern.matches("/auth/(register|login)", routeInfo.requestUrl))
                .toList();

        CasbinRegister.addPolicies(enforcer, LOGIN_PERMISSION, DEFAULT_SYSTEM, filterRoutes);
    }

    @Operation(summary = "用户注册")
    @PostJson("/register")
    public JsonResponse<UserRegisterVo> registerUser(@RequestBody @Validated UserRegisterDto params) {
        UserRegisterVo vo = authService.register(params);
        if (vo.isStatus()) {
            return JsonResponse.success(vo);
        } else {
            return JsonResponse.error(vo);
        }
    }

    @Operation(summary = "用户登录")
    @PostJson("/login")
    public JsonResponse<UserLoginVo> registerUser(@RequestBody @Validated UserLoginDto params) {
        UserLoginVo vo = authService.login(params);
        if (vo.isStatus()) {
            return JsonResponse.success(vo);
        } else {
            return JsonResponse.error(null, vo.getException());
        }
    }
}
