package com.pharmacopoeia.security;

import com.pharmacopoeia.service.AnalyticsService;
import com.pharmacopoeia.util.IpUtils;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.Map;

@Component
public class ApiTrackingFilter extends OncePerRequestFilter {

    private final AnalyticsService analyticsService;

    public ApiTrackingFilter(AnalyticsService analyticsService) {
        this.analyticsService = analyticsService;
    }

    @Override
    protected void doFilterInternal(@NotNull HttpServletRequest request,
                                    @NotNull HttpServletResponse response,
                                    @NotNull FilterChain filterChain) throws ServletException, IOException {
        String requestUri = request.getRequestURI();

        if (!shouldTrack(requestUri)) {
            filterChain.doFilter(request, response);
            return;
        }

        long startTime = System.currentTimeMillis();
        String ip = IpUtils.getClientIp(request);
        String userAgent = request.getHeader("User-Agent");
        String method = request.getMethod();
        String referrer = request.getHeader("Referer");

        try {
            filterChain.doFilter(request, response);
        } finally {
            long elapsedMs = System.currentTimeMillis() - startTime;
            int status = response.getStatus();
            String userKey = getCurrentUserKey();

            Map<String, Object> eventData = Map.of(
                "url", requestUri,
                "method", method,
                "status", status,
                "elapsed_ms", elapsedMs
            );

            analyticsService.saveEvent(
                userKey,
                "api_call",
                eventData,
                requestUri,
                referrer != null ? referrer : "",
                ip,
                userAgent != null ? userAgent : ""
            );
        }
    }

    private boolean shouldTrack(String requestUri) {
        // Don't track the analytics endpoint itself to avoid infinite loop
        return !requestUri.startsWith("/api/v1/analytics/events");
    }

    private String getCurrentUserKey() {
        var auth = org.springframework.security.core.context.SecurityContextHolder
                .getContext().getAuthentication();
        if (auth != null && auth.isAuthenticated()
                && !"anonymousUser".equals(auth.getPrincipal())) {
            return auth.getName();
        }
        return "anonymous";
    }
}
