package com.petshop.backend.config;

import com.petshop.backend.entity.User;
import com.petshop.backend.repository.UserRepository;
import com.petshop.backend.security.AppPrincipal;
import com.petshop.backend.service.ActivityLogService;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

@Component
@Order(Ordered.LOWEST_PRECEDENCE - 20)
public class ActivityLoggingFilter extends OncePerRequestFilter {

    private final UserRepository userRepository;
    private final ActivityLogService activityLogService;

    public ActivityLoggingFilter(UserRepository userRepository, ActivityLogService activityLogService) {
        this.userRepository = userRepository;
        this.activityLogService = activityLogService;
    }

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) {
        String uri = request.getRequestURI();
        if (uri == null || uri.isBlank()) {
            return true;
        }
        if (!uri.startsWith("/api/")) {
            return true;
        }

        String lower = uri.toLowerCase(java.util.Locale.ROOT);
        return lower.startsWith("/api/v1/health")
                || lower.startsWith("/api/v1/activity-logs")
                || lower.startsWith("/v3/api-docs")
                || lower.startsWith("/swagger-ui")
                || lower.startsWith("/ws/");
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        filterChain.doFilter(request, response);
        recordActivity(request, response);
    }

    private void recordActivity(HttpServletRequest request, HttpServletResponse response) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !authentication.isAuthenticated()) {
            return;
        }

        Long userId = null;
        Object principal = authentication.getPrincipal();
        if (principal instanceof AppPrincipal appPrincipal) {
            userId = appPrincipal.getUserId();
        } else if (authentication instanceof UsernamePasswordAuthenticationToken token
                && token.getPrincipal() instanceof AppPrincipal appPrincipal) {
            userId = appPrincipal.getUserId();
        }

        if (userId == null) {
            return;
        }

        User user = userRepository.findById(userId).orElse(null);
        if (user == null) {
            return;
        }

        String activity = String.format("%s %s -> %d", request.getMethod(), request.getRequestURI(), response.getStatus());
        activityLogService.record(user, activity);
    }
}
