package dev.lions.unionflow.server.security;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;

import dev.lions.unionflow.server.service.KeycloakService;
import io.quarkus.test.InjectMock;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.security.TestSecurity;
import jakarta.inject.Inject;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

/**
 * Tests complémentaires pour SecurityConfig.canAccessMemberData.
 * Utilise @InjectMock KeycloakService pour contrôler getCurrentUserId()
 * et couvrir la branche "return true" quand membreId == currentUserId (ligne 195-196).
 */
@QuarkusTest
class SecurityConfigCanAccessTest {

    @Inject
    SecurityConfig securityConfig;

    @InjectMock
    KeycloakService keycloakService;

    // ================================================================
    // canAccessMemberData — branche membreId.equals(getCurrentUserId())
    // ================================================================

    @Test
    @TestSecurity(user = "membre@test.com", roles = {"MEMBRE"})
    @DisplayName("canAccessMemberData retourne true quand membreId correspond à l'ID de l'utilisateur courant (branche ligne 195)")
    void canAccessMemberData_ownData_returnsTrue() {
        String currentUserId = "user-uuid-123";
        when(keycloakService.getCurrentUserId()).thenReturn(currentUserId);
        when(keycloakService.hasRole("MEMBRE")).thenReturn(true);
        when(keycloakService.hasAnyRole(
                SecurityConfig.Roles.ADMIN,
                SecurityConfig.Roles.GESTIONNAIRE_MEMBRE,
                SecurityConfig.Roles.PRESIDENT,
                SecurityConfig.Roles.SECRETAIRE)).thenReturn(false);

        // membreId == currentUserId → branche return true (ligne 196)
        boolean result = securityConfig.canAccessMemberData(currentUserId);

        assertThat(result).isTrue();
    }

    @Test
    @TestSecurity(user = "membre@test.com", roles = {"MEMBRE"})
    @DisplayName("canAccessMemberData retourne false quand membreId différent et utilisateur non gestionnaire")
    void canAccessMemberData_differentId_nonManager_returnsFalse() {
        String currentUserId = "user-uuid-123";
        String autreMembreId = "autre-uuid-456";
        when(keycloakService.getCurrentUserId()).thenReturn(currentUserId);
        when(keycloakService.hasAnyRole(
                SecurityConfig.Roles.ADMIN,
                SecurityConfig.Roles.GESTIONNAIRE_MEMBRE,
                SecurityConfig.Roles.PRESIDENT,
                SecurityConfig.Roles.SECRETAIRE)).thenReturn(false);

        // membreId != currentUserId → pas de canManageMembers → false
        boolean result = securityConfig.canAccessMemberData(autreMembreId);

        assertThat(result).isFalse();
    }

    @Test
    @TestSecurity(user = "admin@test.com", roles = {"ADMIN"})
    @DisplayName("canAccessMemberData retourne true quand gestionnaire accède à des données d'un autre membre")
    void canAccessMemberData_manager_differentId_returnsTrue() {
        String currentUserId = "admin-uuid-789";
        String autreMembreId = "membre-uuid-000";
        when(keycloakService.getCurrentUserId()).thenReturn(currentUserId);
        when(keycloakService.hasAnyRole(
                SecurityConfig.Roles.ADMIN,
                SecurityConfig.Roles.GESTIONNAIRE_MEMBRE,
                SecurityConfig.Roles.PRESIDENT,
                SecurityConfig.Roles.SECRETAIRE)).thenReturn(true);

        // membreId != currentUserId → canManageMembers() = true → return true
        boolean result = securityConfig.canAccessMemberData(autreMembreId);

        assertThat(result).isTrue();
    }
}
