package dev.ksan.etfoglasiserver.service;

import com.google.firebase.messaging.FirebaseMessaging;
import com.google.firebase.messaging.FirebaseMessagingException;
import com.google.firebase.messaging.Message;
import com.google.firebase.messaging.MessagingErrorCode;
import dev.ksan.etfoglasiserver.model.DeviceToken;
import dev.ksan.etfoglasiserver.model.User;
import dev.ksan.etfoglasiserver.repository.DeviceTokenRepo;
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 java.util.List;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
class NotificationServiceTest {

    @Mock
    DeviceTokenRepo deviceTokenRepo;
    @Mock
    FirebaseMessaging firebaseMessaging;
    @InjectMocks
    NotificationService notificationService;

    @Test
    void sendToUser_sendsMessageForEachToken() throws FirebaseMessagingException {
        User user = new User();
        DeviceToken t1 = new DeviceToken(); t1.setFcmToken("token-1");
        DeviceToken t2 = new DeviceToken(); t2.setFcmToken("token-2");

        when(deviceTokenRepo.findByUserId(user.getId()))
                .thenReturn(List.of(t1, t2));
        when(firebaseMessaging.send(any())).thenReturn("msg-id");

        notificationService.sendToUser(user, "Hello", "World");

        verify(firebaseMessaging, times(2)).send(any(Message.class));
    }

    @Test
    void sendToUser_deletesStaleToken_whenUnregistered() throws FirebaseMessagingException {
        User user = new User();
        DeviceToken token = new DeviceToken();
        token.setFcmToken("stale-token");

        when(deviceTokenRepo.findByUserId(user.getId()))
                .thenReturn(List.of(token));

        FirebaseMessagingException ex = mock(FirebaseMessagingException.class);
        when(ex.getMessagingErrorCode()).thenReturn(MessagingErrorCode.UNREGISTERED);
        when(firebaseMessaging.send(any())).thenThrow(ex);

        notificationService.sendToUser(user, "Hello", "World");

        verify(deviceTokenRepo).delete(token);
    }

    @Test
    void sendToUser_doesNothing_whenUserHasNoTokens() throws FirebaseMessagingException {
        User user = new User();
        when(deviceTokenRepo.findByUserId(user.getId())).thenReturn(List.of());

        notificationService.sendToUser(user, "Hello", "World");

        verify(firebaseMessaging, never()).send(any());
    }
}