package incheon.com.security.web;

import incheon.com.security.service.SecurityUserService;
import incheon.com.security.vo.LoginVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Arrays;

/**
 * 세션 기반 사용자 인증 필터
 * - loginVO 세션 확인 → Spring Security 인증 설정
 * - SSO_ID 세션 발견 시 DB 조회하여 loginVO 자동 생성
 */
@Slf4j
@RequiredArgsConstructor
public class AuthenticationFilter extends OncePerRequestFilter {

    private final SecurityUserService securityUserService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        HttpSession session = request.getSession(false);
        LoginVO sessionUser = null;

        if (session != null) {
            sessionUser = (LoginVO) session.getAttribute("loginVO");

            // SSO_ID로 자동 로그인 처리
            if (sessionUser == null) {
                String ssoId = (String) session.getAttribute("SSO_ID");
                if (ssoId != null && !ssoId.isEmpty()) {
                    sessionUser = securityUserService.getUserWithAuthrts(ssoId);

                    if (sessionUser != null) {
                        session.setAttribute("loginVO", sessionUser);
                        securityUserService.updateUserSession(ssoId);
                        session.removeAttribute("SSO_REDIRECT_COUNT");
                        log.info("[SSO] 로그인 성공 - userId: {}, userName: {}", sessionUser.getUserId(), sessionUser.getUserNm());
                    } else {
                        session.removeAttribute("SSO_ID");
                        log.warn("[SSO] 사용자 없음 - ssoId: {} (DB 미등록)", ssoId);
                    }
                }
            }
        }

        if (sessionUser != null && sessionUser.getAuthorities() != null && !sessionUser.getAuthorities().isEmpty()) {
            Authentication auth = new UsernamePasswordAuthenticationToken(
                    sessionUser, null, sessionUser.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(auth);

        } else if (sessionUser != null && sessionUser.getGroupId() != null) {
            // 레거시: groupId 방식 지원
            Authentication auth = new UsernamePasswordAuthenticationToken(
                    sessionUser, null, Arrays.asList(new SimpleGrantedAuthority(sessionUser.getGroupId())));
            SecurityContextHolder.getContext().setAuthentication(auth);

        } else {
            SecurityContextHolder.clearContext();
        }

        filterChain.doFilter(request, response);
    }
    
    /**
     * 데이터베이스에서 사용자 정보 조회
     */
    public LoginVO getUser(String userId) {
        if (securityUserService == null) {
            return null;
        }
        return securityUserService.getUserById(userId);
    }
} 