package mx.gob.jumapacelaya.api;

import com.vaadin.flow.spring.security.VaadinWebSecurity;
import mx.gob.jumapacelaya.services.UserService;
import mx.gob.jumapacelaya.views.login.LoginView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.ldap.core.support.LdapContextSource;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@EnableWebSecurity
@Configuration
public class SecurityConfig extends VaadinWebSecurity {
    private static final Logger log = LoggerFactory.getLogger(SecurityConfig.class);

    private UserService userService;

    public void setUserService(UserService userService) {
        this.userService = userService;
    }


    @Override
    public void configure(WebSecurity web) throws Exception {
        // Customize your WebSecurity configuration.
        super.configure(web);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(auth -> auth
                        .requestMatchers(
                                AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/icons/*.png"),
                                AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/images/*.png")
                        ).permitAll()
                        .requestMatchers(
                                AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/login*")
                        ).permitAll()
                )
                .formLogin(formLogin -> formLogin
                        .loginPage("/login")
                        .successHandler((request, response, authentication) -> {
                            String username = authentication.getName();
                            log.debug("Configure:loginSuccess: {}", authentication.getName());
                            var user = userService.getAuthenticatedRedmineUser();
                            log.debug("Authenticated user: {}", user);

                            if (user == null) {
                                log.warn("Usuario autenticado pero no encontrado en Redmine. Redirigiendo a página de error.");
                                response.sendRedirect("");
                            } else {
                                response.sendRedirect("");
                            }
                        })
                        .failureUrl("/login?error=true")  // Corrigiendo la URL de fallo
                );
        super.configure(http);
        setLoginView(http, LoginView.class);
    }

    @Autowired
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider("JUMAPACELAYA.GOB.MX", "ldap://172.16.0.1");
        provider.setConvertSubErrorCodesToExceptions(true);
        provider.setUseAuthenticationRequestCredentials(true);
        auth.authenticationProvider(provider);
    }

    @Value("${spring.ldap.urls}")
    private String ldapUrls;

    @Value("${spring.ldap.base}")
    private String ldapBase;

    @Value("${spring.ldap.password}")
    private String ldapPassword;

    @Bean
    public LdapContextSource ldapContextSource() {
        LdapContextSource contextSource = new LdapContextSource();
        contextSource.setUrl(ldapUrls);
        contextSource.setBase(ldapBase);
        contextSource.setUserDn("administrator");
        contextSource.setPassword(ldapPassword);
        contextSource.setPooled(true);
        contextSource.setReferral("follow");
        return contextSource;
    }
}
