package org.raddatz.familienarchiv.audit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import org.raddatz.familienarchiv.user.AppUser;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;

import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyCollection;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class AuditLogQueryServiceTest {

    @Mock AuditLogQueryRepository queryRepository;
    @InjectMocks AuditLogQueryService auditLogQueryService;

    @Test
    void findActivityFeed_withKinds_passesKindNamesToRepository() {
        UUID userId = UUID.randomUUID();
        Set<AuditKind> kinds = Set.of(AuditKind.FILE_UPLOADED);
        when(queryRepository.findRolledUpActivityFeed(eq(userId.toString()), eq(10), anyCollection()))
                .thenReturn(List.of());

        List<ActivityFeedRow> result = auditLogQueryService.findActivityFeed(userId, 10, kinds);

        assertThat(result).isEmpty();
        verify(queryRepository).findRolledUpActivityFeed(eq(userId.toString()), eq(10),
                eq(List.of("FILE_UPLOADED")));
    }

    @Test
    void findActivityFeed_twoArg_defaultsToAllRollupEligibleKinds() {
        UUID userId = UUID.randomUUID();
        when(queryRepository.findRolledUpActivityFeed(eq(userId.toString()), eq(10), anyCollection()))
                .thenReturn(List.of());

        auditLogQueryService.findActivityFeed(userId, 10);

        verify(queryRepository).findRolledUpActivityFeed(eq(userId.toString()), eq(10),
                eq(AuditKind.ROLLUP_ELIGIBLE.stream().map(Enum::name).toList()));
    }

    @Test
    void findRecentUserManagementEvents_delegatesToRepositoryWithAllThreeKinds() {
        AuditLog entry = AuditLog.builder().id(UUID.randomUUID()).kind(AuditKind.USER_CREATED).build();
        when(queryRepository.findByKindIn(anyCollection(), any(Pageable.class)))
                .thenReturn(new PageImpl<>(List.of(entry)));

        List<AuditLog> result = auditLogQueryService.findRecentUserManagementEvents(5);

        assertThat(result).containsExactly(entry);
        verify(queryRepository).findByKindIn(
                argThat((Collection<AuditKind> kinds) ->
                        kinds.contains(AuditKind.USER_CREATED) &&
                        kinds.contains(AuditKind.USER_DELETED) &&
                        kinds.contains(AuditKind.GROUP_MEMBERSHIP_CHANGED)),
                any(Pageable.class));
    }
}
