package com.mobicule.mcollectsettlementnew.security;

import com.mobicule.mcollectsettlementnew.openid.CustomDefaultJmixOidcUserService;
import io.jmix.core.CoreProperties;
import io.jmix.core.JmixOrder;
import io.jmix.core.security.UserRepository;
import io.jmix.security.authentication.RoleGrantedAuthority;
import io.jmix.security.model.ResourceRole;
import io.jmix.security.role.ResourceRoleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.client.oidc.web.logout.OidcClientInitiatedLogoutSuccessHandler;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.web.SecurityFilterChain;

import java.util.ArrayList;
import java.util.Collection;

@Configuration
public class OAuthSecurityConfig {

    @Autowired
    private ClientRegistrationRepository clientRegistrationRepository;

    @Autowired
    private ResourceRoleRepository resourceRoleRepository;

    @Bean
    @Order(JmixOrder.HIGHEST_PRECEDENCE + 100)
    public SecurityFilterChain securityFilterChain(HttpSecurity http, UserRepository userRepository,
                                                   CoreProperties coreProperties,
                                                   CustomDefaultJmixOidcUserService customOidcUserService) throws Exception { // Inject your custom service here
        http.authorizeHttpRequests(authorize -> authorize
                        .anyRequest().permitAll() // Consider more restrictive access for authenticated users
                )
                .anonymous(anonymous -> anonymous
                        .principal(userRepository.getAnonymousUser())
                        .key(coreProperties.getAnonymousAuthenticationTokenKey())
                )
                .oauth2Login(configurer -> {
                    configurer
                            .userInfoEndpoint(userInfo -> userInfo
                                    .oidcUserService(customOidcUserService) // <--- Crucial: Register your custom service
                            );
                })
                .logout(logout -> logout.logoutSuccessUrl("/#login"))
                .csrf(csrf -> csrf.disable())
                .headers(headers -> headers.frameOptions().sameOrigin());
        return http.build();
    }
    /**
     * Builds granted authority list that grants access to the FullAccess role
     */
    private Collection<GrantedAuthority> getDefaultGrantedAuthorities() {
        ResourceRole fullAccessRole = resourceRoleRepository.getRoleByCode(FullAccessRole.CODE);
        RoleGrantedAuthority authority = RoleGrantedAuthority.ofResourceRole(fullAccessRole);
        Collection<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(authority);
        return authorities;
    }

    private OidcClientInitiatedLogoutSuccessHandler oidcLogoutSuccessHandler() {
        OidcClientInitiatedLogoutSuccessHandler successHandler = new OidcClientInitiatedLogoutSuccessHandler(clientRegistrationRepository);
        successHandler.setPostLogoutRedirectUri("{baseUrl}");
        return successHandler;
    }

}
