package cn.meowrain.aioj.backend.framework.security.config;

import cn.meowrain.aioj.backend.framework.security.autoconfigure.SecurityAutoConfiguration;
import cn.meowrain.aioj.backend.framework.security.filter.JwtAuthenticationFilter;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
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 java.util.List;


@AutoConfiguration(after = SecurityAutoConfiguration.class)
@EnableWebSecurity
@RequiredArgsConstructor
@ConditionalOnProperty(prefix = "jwt", name = "enabled", havingValue = "true", matchIfMissing = true)
@ConditionalOnBean(JwtAuthenticationFilter.class)
public class SecurityConfiguration {

	private final JwtAuthenticationFilter jwtAuthenticationFilter;

	@Bean
	@ConditionalOnMissingBean(SecurityFilterChain.class)
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http.csrf(csrf -> csrf.disable())
			.cors(cors -> cors.configurationSource(corsConfigurationSource()))
			.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
			.authorizeHttpRequests(auth -> auth
				// Swagger 文档路径
				.requestMatchers("/doc.html", "/swagger-ui/**", "/swagger-resources/**", "/webjars/**",
						"/v3/api-docs/**", "/v3/api-docs", "/favicon.ico")
				.permitAll()
				// 用户注册、发送验证码等公开接口
				.requestMatchers("/v1/user/register", "/v1/user/email/send-code",
						"/api/v1/user/register", "/api/v1/user/email/send-code")
				.permitAll()
				// 文件访问接口（公开，用于访问图片等静态资源）
				.requestMatchers("/file/**", "/api/file/**")
				.permitAll()
				// 内部服务调用路径（Feign）- 使用具体路径匹配
				.requestMatchers("/v1/user/inner/**", "/v1/*/inner/**", 
						"/api/v1/user/inner/**", "/api/v1/*/inner/**")
				.permitAll()
				// 其他请求需要认证（可由子类覆盖此配置）
				.anyRequest()
				.permitAll())
			.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
		return http.build();
	}

	@Bean
	@ConditionalOnMissingBean(CorsConfigurationSource.class)
	public CorsConfigurationSource corsConfigurationSource() {
		CorsConfiguration configuration = new CorsConfiguration();
		configuration.setAllowedOriginPatterns(List.of("*"));
		configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"));
		configuration.setAllowedHeaders(List.of("*"));
		configuration.setAllowCredentials(true);
		configuration.setMaxAge(3600L);
		
		UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
		source.registerCorsConfiguration("/**", configuration);
		return source;
	}

}
