package com.takensoft.common.oauth.handler;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * @author takensoft
 * @since 2025.05.22
 * @modification
 *     since    |    author    | description
 *  2025.05.22  |  takensoft   | 최초 등록
 *
 * OAuth2 로그인 실패 핸들러
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class OAuth2AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {

    @Value("${front.url}")
    private String FRONT_URL;

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException{

        String errorMessage = mapErrorMessage(exception);
        String encodedMessage = URLEncoder.encode(errorMessage, StandardCharsets.UTF_8);

        String redirectUrl = String.format("%s/login?error=oauth2_failed&message=%s",
                FRONT_URL, encodedMessage);

        getRedirectStrategy().sendRedirect(request, response, redirectUrl);
    }

    /**
     * 에러 메시지 매핑
     */
    private String mapErrorMessage(AuthenticationException exception) {
        String message = exception.getMessage();

        if (message == null) {
            return "OAuth2 로그인에 실패했습니다.";
        }
        if (message.contains("access_denied")) {
            return "사용자가 인증을 취소했습니다.";
        }
        if (message.contains("invalid_request")) {
            return "잘못된 OAuth2 요청입니다.";
        }
        if (message.contains("unauthorized_client")) {
            return "인증되지 않은 클라이언트입니다.";
        }
        if (message.contains("server_error")) {
            return "OAuth2 서버 오류가 발생했습니다.";
        }

        return "OAuth2 로그인에 실패했습니다.";
    }
}