package com.unicorn.hgzero.user.controller;

import com.unicorn.hgzero.common.dto.ApiResponse;
import com.unicorn.hgzero.user.config.jwt.UserPrincipal;
import com.unicorn.hgzero.user.dto.*;
import com.unicorn.hgzero.user.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

/**
 * 사용자 인증 Controller
 * 로그인, 토큰 갱신, 로그아웃, 토큰 검증 API 제공
 */
@Slf4j
@RestController
@RequestMapping("/api/auth")
@RequiredArgsConstructor
@Tag(name = "User Authentication", description = "사용자 인증 API")
public class UserController {

    private final UserService userService;

    /**
     * 사용자 로그인
     * LDAP 인증 수행 후 JWT 토큰 발급
     *
     * @param request 로그인 요청 정보 (userId, password)
     * @return 로그인 응답 (Access Token, Refresh Token, 사용자 정보)
     */
    @PostMapping("/login")
    @Operation(
            summary = "사용자 로그인",
            description = "LDAP 인증 수행 후 JWT Access Token과 Refresh Token을 발급합니다."
    )
    public ResponseEntity<ApiResponse<LoginResponse>> login(
            @Valid @RequestBody LoginRequest request) {

        log.info("로그인 요청: userId={}", request.getUserId());

        LoginResponse response = userService.login(request);

        return ResponseEntity.ok(ApiResponse.success("로그인 성공", response));
    }

    /**
     * Access Token 갱신
     * Refresh Token을 사용하여 새로운 Access Token 발급
     *
     * @param request Refresh Token 요청 정보
     * @return 새로운 Access Token
     */
    @PostMapping("/refresh")
    @Operation(
            summary = "Access Token 갱신",
            description = "Refresh Token을 사용하여 새로운 Access Token을 발급합니다."
    )
    public ResponseEntity<ApiResponse<RefreshTokenResponse>> refresh(
            @Valid @RequestBody RefreshTokenRequest request) {

        log.info("토큰 갱신 요청");

        RefreshTokenResponse response = userService.refresh(request);

        return ResponseEntity.ok(ApiResponse.success("토큰 갱신 성공", response));
    }

    /**
     * 로그아웃
     * Refresh Token 삭제
     *
     * @param request 로그아웃 요청 정보 (선택적 Refresh Token)
     * @param userPrincipal 인증된 사용자 정보
     * @return 로그아웃 성공 메시지
     */
    @PostMapping("/logout")
    @Operation(
            summary = "로그아웃",
            description = "Refresh Token을 삭제하고 로그아웃합니다."
    )
    public ResponseEntity<ApiResponse<Void>> logout(
            @RequestBody(required = false) LogoutRequest request,
            @AuthenticationPrincipal UserPrincipal userPrincipal) {

        log.info("로그아웃 요청: userId={}", userPrincipal.getUserId());

        userService.logout(request, userPrincipal.getUserId());

        return ResponseEntity.ok(ApiResponse.success("로그아웃 성공", null));
    }

    /**
     * Access Token 검증
     * 토큰 유효성 검증 및 사용자 정보 반환
     *
     * @param authorization Authorization 헤더 (Bearer {token})
     * @return 토큰 검증 결과 및 사용자 정보
     */
    @GetMapping("/validate")
    @Operation(
            summary = "Access Token 검증",
            description = "Access Token의 유효성을 검증하고 사용자 정보를 반환합니다."
    )
    public ResponseEntity<ApiResponse<TokenValidateResponse>> validate(
            @Parameter(description = "Bearer {token}", required = true)
            @RequestHeader("Authorization") String authorization) {

        log.info("토큰 검증 요청");

        // Bearer 제거
        String token = authorization.replace("Bearer ", "");

        TokenValidateResponse response = userService.validateToken(token);

        if (response.getValid()) {
            return ResponseEntity.ok(ApiResponse.success("토큰 검증 성공", response));
        } else {
            return ResponseEntity.ok(ApiResponse.success("토큰 검증 실패", response));
        }
    }
}
