package com.dne.ems.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import lombok.RequiredArgsConstructor;

/**
 * 安全配置类，定义系统安全策略
 *
 * <p>主要配置：
 * <ul>
 *   <li>HTTP安全过滤器链</li>
 *   <li>CORS跨域配置</li>
 *   <li>认证管理器</li>
 *   <li>密码编码器</li>
 * </ul>
 *
 * <p>安全特性：
 * <ul>
 *   <li>基于JWT的无状态认证</li>
 *   <li>CSRF防护禁用(因使用JWT)</li>
 *   <li>方法级权限控制</li>
 *   <li>细粒度URL访问控制</li>
 * </ul>
 *
 * @author DNE开发团队
 * @version 1.0
 * @since 2024-03
 */
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true, proxyTargetClass = true)
@RequiredArgsConstructor
public class SecurityConfig {

    private final JwtAuthenticationFilter jwtAuthenticationFilter;

    /**
     * 配置HTTP安全过滤器链
     *
     * <p>安全规则：
     * <ul>
     *   <li>禁用CSRF(因使用JWT)</li>
     *   <li>启用CORS跨域支持</li>
     *   <li>设置无状态会话</li>
     *   <li>配置URL访问权限</li>
     *   <li>添加JWT认证过滤器</li>
     * </ul>
     *
     * @param http HTTP安全构建器
     * @return 安全过滤器链
     * @throws Exception 如果配置出错
     */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf(AbstractHttpConfigurer::disable)
                .cors(cors -> cors.configurationSource(corsConfigurationSource()))
                .authorizeHttpRequests(authorize -> authorize
                        // 允许所有OPTIONS预检请求
                        .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                        // 明确允许匿名访问的端点
                        .requestMatchers("/api/auth/**").permitAll()
                        .requestMatchers(
                                "/api/auth/login",
                                "/api/auth/signup",
                                "/api/auth/send-verification-code",
                                "/api/auth/send-password-reset-code",
                                "/api/auth/reset-password-with-code"
                        ).permitAll()
                        // 明确地将logout端点设置为需要认证
                        .requestMatchers("/api/auth/logout").hasAnyRole("ADMIN", "DECISION_MAKER", "GRID_WORKER")
                        // 公共数据和API
                        .requestMatchers(
                                "/api/public/**",
                                "/api/map/**",       // 允许访问地图数据
                                "/api/pathfinding/**", // 允许访问寻路功能
                                "/api/files/view/**",
                                "/api/files/download/**",
                                "/swagger-ui/**",
                                "/v3/api-docs/**",
                                "/swagger-ui.html"
                        ).permitAll()
                        .requestMatchers("/api/files/**").permitAll()
                        // 添加操作日志端点权限控制
                        .requestMatchers("/api/logs/my-logs").authenticated()
                        .requestMatchers("/api/logs").hasRole("ADMIN")
                        // 明确保护Dashboard端点
                        .requestMatchers(
                            "/api/dashboard/stats",
                            "/api/dashboard/reports/aqi-distribution",
                            // ... (other dashboard endpoints)
                            "/api/dashboard/reports/aqi-trends-24h"
                        ).hasAnyRole("ADMIN", "DECISION_MAKER")
                        // 其他所有请求都需要认证
                        .anyRequest().authenticated() // <--- 确保这一行存在且位于末尾
                )
                .sessionManagement(session -> session
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                )
                
                .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
                
        return http.build();
    }

    /**
     * 配置CORS跨域资源共享
     *
     * <p>允许规则：
     * <ul>
     *   <li>所有来源(*)</li>
     *   <li>所有HTTP方法</li>
     *   <li>所有HTTP头</li>
     * </ul>
     *
     * @return CORS配置源
     */
    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.addAllowedOrigin("*"); // 允许所有来源
        configuration.addAllowedMethod("*"); // 允许所有HTTP方法
        configuration.addAllowedHeader("*"); // 允许所有HTTP头
        // configuration.setAllowCredentials(true); // 如果需要携带凭证（如cookies），请取消注释
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration); // 对所有路径应用CORS配置
        return source;
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}