package com.datamate.common.auth.interfaces.rest;

import com.datamate.common.auth.application.AuthApplicationService;
import com.datamate.common.auth.domain.model.AuthPermissionInfo;
import com.datamate.common.auth.domain.model.AuthRoleInfo;
import com.datamate.common.auth.interfaces.rest.dto.AssignUserRolesRequest;
import com.datamate.common.auth.interfaces.rest.dto.AuthCurrentUserResponse;
import com.datamate.common.auth.interfaces.rest.dto.AuthLoginResponse;
import com.datamate.common.auth.interfaces.rest.dto.AuthUserWithRolesResponse;
import com.datamate.common.auth.interfaces.rest.dto.LoginRequest;
import com.datamate.common.infrastructure.exception.BusinessAssert;
import com.datamate.common.auth.infrastructure.exception.AuthErrorCode;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * 认证授权控制器
 */
@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
public class AuthController {
    private final AuthApplicationService authApplicationService;

    @PostMapping("/login")
    public AuthLoginResponse login(@RequestBody @Valid LoginRequest loginRequest) {
        return authApplicationService.login(loginRequest.username(), loginRequest.password());
    }

    @GetMapping("/me")
    public AuthCurrentUserResponse me(HttpServletRequest request) {
        return authApplicationService.getCurrentUser(extractBearerToken(request.getHeader("Authorization")));
    }

    @PostMapping("/refresh")
    public AuthLoginResponse refresh(@RequestHeader("Authorization") String authorization) {
        return authApplicationService.refreshToken(extractBearerToken(authorization));
    }

    @GetMapping("/users")
    public List<AuthUserWithRolesResponse> listUsers() {
        return authApplicationService.listUsersWithRoles();
    }

    @PutMapping("/users/{userId}/roles")
    public void assignRoles(@PathVariable("userId") Long userId,
                            @RequestBody @Valid AssignUserRolesRequest request) {
        authApplicationService.assignUserRoles(userId, request.roleIds());
    }

    @GetMapping("/roles")
    public List<AuthRoleInfo> listRoles() {
        return authApplicationService.listRoles();
    }

    @GetMapping("/permissions")
    public List<AuthPermissionInfo> listPermissions() {
        return authApplicationService.listPermissions();
    }

    private String extractBearerToken(String authorizationHeader) {
        BusinessAssert.isTrue(
                authorizationHeader != null && authorizationHeader.startsWith("Bearer "),
                AuthErrorCode.TOKEN_INVALID
        );
        String token = authorizationHeader.substring("Bearer ".length()).trim();
        BusinessAssert.isTrue(!token.isEmpty(), AuthErrorCode.TOKEN_INVALID);
        return token;
    }
}

