package com.dacrt.SBIABackend.security;

import java.util.Arrays;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.http.SessionCreationPolicy;
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.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import com.dacrt.SBIABackend.security.jwt.JwtEntryPoint;
import com.dacrt.SBIABackend.security.jwt.JwtTokenFilter;
import com.dacrt.SBIABackend.security.service.UsuarioDetailServiceImpl;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class MainSecurity {

    @Autowired
    UsuarioDetailServiceImpl userDetailsServiceImpl;

    @Autowired
    JwtEntryPoint jwtEntryPoint;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    JwtTokenFilter jwtTokenFilter;

    AuthenticationManager authenticationManager;
    
    @Value("${cors.allowed.origin}") 
    private List<String> allowedOrigin;

    /*@Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        AuthenticationManagerBuilder builder = http.getSharedObject(AuthenticationManagerBuilder.class);
        builder.userDetailsService(userDetailsServiceImpl).passwordEncoder(passwordEncoder);
        authenticationManager = builder.build();
        http.authenticationManager(authenticationManager);

        http.csrf(csrf -> csrf.disable());
        http.cors(Customizer.withDefaults());
        http.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
        http.authorizeHttpRequests(auth -> auth.antMatchers("/security/**","/home/**",
                        "/email-password/**",
                        "/favicon.ico",
                        "/security/oAuth2/callback",
                        "/security/oAuth2/login",
                        "/login",
                        "/auditoria/**",
                        "/v2/api-docs/**",
                        "/swagger-ui/**",
                        "/swagger-resources/**",
                        "/configuration/**",
                        "/parametrosseguridad/**"
                        ).permitAll()
                .anyRequest().authenticated());
        http.exceptionHandling(exc -> exc.authenticationEntryPoint(jwtEntryPoint));
        http.addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }*/
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    	if (!allowedOrigin.isEmpty())
        // Imprimimos para estar seguros de qué valor está cargando el VPS
        System.out.println("CORS ORIGIN CARGADO: " + allowedOrigin);

     // 1. Configuración de CORS única
        //http.cors(cors -> cors.configurationSource(corsConfigurationSource()));
        
        AuthenticationManagerBuilder builder = http.getSharedObject(AuthenticationManagerBuilder.class);
        builder.userDetailsService(userDetailsServiceImpl).passwordEncoder(passwordEncoder);
        authenticationManager = builder.build();
        http.authenticationManager(authenticationManager);

        

        // 2. Deshabilitar CSRF (necesario para APIs Stateless)
        http.csrf(csrf -> csrf.disable());

        
        if (!allowedOrigin.isEmpty()) {
        	 // 4. Autorización de rutas
            http.authorizeHttpRequests(auth -> auth
            	.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .antMatchers("/security/**", "/home/**", "/email-password/**",
                             "/favicon.ico", "/security/oAuth2/callback",
                             "/security/oAuth2/login", "/login", "/auditoria/**",
                             "/v2/api-docs/**", "/swagger-ui/**", "/swagger-resources/**",
                             "/configuration/**", "/parametrosseguridad/**").permitAll()
                .anyRequest().authenticated());
        }else{
        	 // 4. Autorización de rutas
            http.authorizeHttpRequests(auth -> auth
                .antMatchers("/security/**", "/home/**", "/email-password/**",
                             "/favicon.ico", "/security/oAuth2/callback",
                             "/security/oAuth2/login", "/login", "/auditoria/**",
                             "/v2/api-docs/**", "/swagger-ui/**", "/swagger-resources/**",
                             "/configuration/**", "/parametrosseguridad/**").permitAll()
                .anyRequest().authenticated());
        }
        	
       

     // 3. Política de sesión (SOLO UNA VEZ)
        http.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
        
        http.exceptionHandling(exc -> exc.authenticationEntryPoint(jwtEntryPoint));
        http.addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }

    @Bean
    public FilterRegistrationBean<CorsFilter> corsConfigurationSource() {
    	UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration configuration = new CorsConfiguration();
        
        // IMPORTANTE: Asegúrate de que allowedOrigin en el properties sea http://172.235.141.167:8083
        configuration.setAllowedOrigins(allowedOrigin); 
        
        configuration.setAllowedMethods(Arrays.asList("*"));
        
        // Agregamos cabeceras comunes para que no falle por falta de headers
        configuration.setAllowedHeaders(Arrays.asList("*"));
        
        configuration.setAllowCredentials(true);

        
        source.registerCorsConfiguration("/**", configuration);
        FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
        // ESTA ES LA CLAVE: Se ejecuta antes que cualquier otra cosa en el servidor
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE); 
        return bean;
       
    }

    
    /*
    @Bean
    public JwtTokenFilter jwtTokenFilter(){
        return new JwtTokenFilter();
    }

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

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable()
                .authorizeRequests()
                .antMatchers(
                        "/auth/**",
                        "/email-password/**",
                        "/v2/api-docs/**",
                        "/swagger-ui/**",
                        "/swagger-resources/**",
                        "/configuration/**"
                ).permitAll()
                .anyRequest().authenticated()
                .and()
                .exceptionHandling().authenticationEntryPoint(jwtEntryPoint)
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.addFilterBefore(jwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    }*/
}