package org.raddatz.familienarchiv.security;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.raddatz.familienarchiv.exception.DomainException;
import org.raddatz.familienarchiv.user.AppUser;
import org.raddatz.familienarchiv.user.UserService;
import org.springframework.security.core.Authentication;

import java.util.UUID;

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

@ExtendWith(MockitoExtension.class)
class SecurityUtilsTest {

    @Mock Authentication authentication;
    @Mock UserService userService;

    @Test
    void requireUserId_throwsUnauthorized_whenAuthenticationIsNull() {
        assertThatThrownBy(() -> SecurityUtils.requireUserId(null, userService))
                .isInstanceOf(DomainException.class);
    }

    @Test
    void requireUserId_throwsUnauthorized_whenNotAuthenticated() {
        when(authentication.isAuthenticated()).thenReturn(false);
        assertThatThrownBy(() -> SecurityUtils.requireUserId(authentication, userService))
                .isInstanceOf(DomainException.class);
    }

    @Test
    void requireUserId_throwsUnauthorized_whenUserNotFound() {
        when(authentication.isAuthenticated()).thenReturn(true);
        when(authentication.getName()).thenReturn("ghost@example.com");
        when(userService.findByEmail("ghost@example.com")).thenReturn(null);
        assertThatThrownBy(() -> SecurityUtils.requireUserId(authentication, userService))
                .isInstanceOf(DomainException.class);
    }

    @Test
    void requireUserId_returnsUserId_whenAuthenticated() {
        UUID userId = UUID.randomUUID();
        AppUser user = AppUser.builder().id(userId).email("user@example.com").password("pw").build();
        when(authentication.isAuthenticated()).thenReturn(true);
        when(authentication.getName()).thenReturn("user@example.com");
        when(userService.findByEmail("user@example.com")).thenReturn(user);

        UUID result = SecurityUtils.requireUserId(authentication, userService);

        assertThat(result).isEqualTo(userId);
    }
}
