package com.pharmacopoeia.security;

import com.pharmacopoeia.config.AuthProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;

import java.util.List;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    private final JwtAuthFilter jwtAuthFilter;
    private final RateLimitFilter rateLimitFilter;
    private final ApiTrackingFilter apiTrackingFilter;
    private final AuthProperties authProperties;

    public SecurityConfig(JwtAuthFilter jwtAuthFilter, RateLimitFilter rateLimitFilter,
                          ApiTrackingFilter apiTrackingFilter, AuthProperties authProperties) {
        this.jwtAuthFilter = jwtAuthFilter;
        this.rateLimitFilter = rateLimitFilter;
        this.apiTrackingFilter = apiTrackingFilter;
        this.authProperties = authProperties;
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.cors(cors -> cors.configurationSource(corsConfigSource()))
                .csrf(AbstractHttpConfigurer::disable)
                .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS));

        if (authProperties.isEnabled()) {
            // 生产模式：所有 /api/** 需要鉴权，公开路径仅限登录和静态资源
            http.authorizeHttpRequests(auth -> auth
                    .requestMatchers("/health",
                            "/api/v1/auth/**",
                            "/api/v1/yaodian/**",
                            "/api/v1/analytics/**")
                    .permitAll()
                    .requestMatchers("/static/**", "/", "/favicon.ico").permitAll()
                    .requestMatchers("/api/**").authenticated()
                    .anyRequest().permitAll()
            );
        } else {
            // 开发模式：全部放行
            http.authorizeHttpRequests(auth -> auth.anyRequest().permitAll());
        }

        // Filter order:
        // 1. RateLimitFilter - first reject rate-limited requests (don't track them)
        // 2. JwtAuthFilter - authenticate user so userKey is available
        // 3. ApiTrackingFilter - now we can track with userKey
        http.addFilterBefore(rateLimitFilter, UsernamePasswordAuthenticationFilter.class);
        http.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
        http.addFilterBefore(apiTrackingFilter, UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }

    @Bean
    public CorsConfigurationSource corsConfigSource() {
        return request -> {
            var config = new CorsConfiguration();
            // 回射请求的 Origin，避免 allowCredentials=true 与 "*" 互斥
            String origin = request.getHeader("Origin");
            config.setAllowedOrigins(List.of(origin != null ? origin : "*"));
            config.setAllowedMethods(List.of("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
            config.setAllowedHeaders(List.of("*"));
            config.setAllowCredentials(true);
            return config;
        };
    }
}
