package gc.mda.kcg.auth;

import io.jsonwebtoken.Claims;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.Arrays;

@Slf4j
@Component
@RequiredArgsConstructor
public class AuthFilter extends OncePerRequestFilter {

    private static final String JWT_COOKIE_NAME = "kcg_token";
    private static final String AUTH_PATH_PREFIX = "/api/auth/";
    private static final String SENSOR_PATH_PREFIX = "/api/sensor/";
    private static final String CCTV_PATH_PREFIX = "/api/cctv/";
    private static final String VESSEL_ANALYSIS_PATH_PREFIX = "/api/vessel-analysis";
    private static final String PREDICTION_PATH_PREFIX = "/api/prediction/";

    private final JwtProvider jwtProvider;

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) {
        String path = request.getRequestURI();
        return path.startsWith(AUTH_PATH_PREFIX)
                || path.startsWith(SENSOR_PATH_PREFIX)
                || path.startsWith(CCTV_PATH_PREFIX)
                || path.startsWith(VESSEL_ANALYSIS_PATH_PREFIX)
                || path.startsWith(PREDICTION_PATH_PREFIX);
    }

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

        String token = extractTokenFromCookies(request);

        if (token == null || token.isBlank()) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getWriter().write("{\"error\":\"인증이 필요합니다.\"}");
            return;
        }

        try {
            Claims claims = jwtProvider.validateToken(token);
            request.setAttribute("userEmail", claims.getSubject());
            request.setAttribute("userName", claims.get("name", String.class));
            filterChain.doFilter(request, response);
        } catch (IllegalArgumentException e) {
            log.warn("인증 실패: {}", e.getMessage());
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getWriter().write("{\"error\":\"유효하지 않은 토큰입니다.\"}");
        }
    }

    private String extractTokenFromCookies(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if (cookies == null) {
            return null;
        }
        return Arrays.stream(cookies)
                .filter(c -> JWT_COOKIE_NAME.equals(c.getName()))
                .findFirst()
                .map(Cookie::getValue)
                .orElse(null);
    }
}
