package com.example.demo.security;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.NonNull;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import com.example.demo.model.User;
import com.example.demo.repository.UserRepository;
import com.example.demo.util.JwtUtils;

import io.jsonwebtoken.ExpiredJwtException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

/**
 * JWT认证过滤器
 * 注意：直接使用 UserRepository 而不是 UserService，避免循环依赖
 */
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationFilter.class);

    private final JwtUtils jwtUtils;
    private final UserRepository userRepository;

    public JwtAuthenticationFilter(JwtUtils jwtUtils, UserRepository userRepository) {
        this.jwtUtils = jwtUtils;
        this.userRepository = userRepository;
    }

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

        String requestURI = request.getRequestURI();

        // 定义不需要JWT验证的路径
        String[] publicPaths = {
            "/api/auth/login",
            "/api/auth/login/email",
            "/api/auth/register",
            "/api/verification/",
            "/api/public/",
            "/api/email/",
            "/api/payments/alipay/notify",
            "/api/payments/alipay/return",
            "/api/payments/lulupay/notify",
            "/api/payments/lulupay/return",
            "/api/payment/paypal/success",
            "/api/payment/paypal/cancel",
            "/swagger-ui",
            "/v3/api-docs",
            "/api-docs"
        };

        // 检查是否是公开路径
        boolean isPublicPath = false;
        for (String publicPath : publicPaths) {
            if (requestURI.contains(publicPath)) {
                isPublicPath = true;
                break;
            }
        }

        // 如果是公开路径，直接放行
        if (isPublicPath) {
            filterChain.doFilter(request, response);
            return;
        }

        try {
            String authHeader = request.getHeader("Authorization");
            String token = jwtUtils.extractTokenFromHeader(authHeader);

            if (token != null && !token.equals("null") && !token.trim().isEmpty()) {
                String username = jwtUtils.getUsernameFromToken(token);

                if (username != null && jwtUtils.validateToken(token, username)) {
                    // 直接使用 Repository 查询用户
                    User user = userRepository.findByUsername(username).orElse(null);

                    if (user != null) {
                        // 检查用户是否被封禁
                        if (user.getIsActive() == null || !user.getIsActive()) {
                            logger.warn("用户已被封禁，拒绝访问: {}", username);
                            SecurityContextHolder.clearContext();
                            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                            response.setContentType("application/json;charset=UTF-8");
                            response.getWriter().write("{\"success\":false,\"code\":403,\"message\":\"您的账号已被封禁，请联系管理员\"}");
                            return;
                        }
                        
                        List<GrantedAuthority> authorities = new ArrayList<>();
                        authorities.add(new SimpleGrantedAuthority(user.getRole()));

                        UsernamePasswordAuthenticationToken authToken =
                            new UsernamePasswordAuthenticationToken(user.getUsername(), null, authorities);
                        authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                        SecurityContextHolder.getContext().setAuthentication(authToken);
                    } else {
                        logger.warn("JWT中的用户不存在: {}", username);
                    }
                }
            }
        } catch (ExpiredJwtException e) {
            logger.warn("JWT已过期: {}", e.getMessage());
            SecurityContextHolder.clearContext();
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write("{\"success\":false,\"code\":401,\"message\":\"登录已过期，请重新登录\"}");
            return;
        } catch (Exception e) {
            logger.warn("JWT认证失败: {}", e.getMessage());
            SecurityContextHolder.clearContext();
        }

        filterChain.doFilter(request, response);
    }
}
