package com.njcn.rdms.module.project.framework.notify;

import com.njcn.rdms.framework.test.core.ut.BaseMockitoUnitTest;
import com.njcn.rdms.module.system.api.notify.NotifyMessageSendApi;
import com.njcn.rdms.module.system.enums.notify.NotifyMessageLevelConstants;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

/**
 * {@link NotifySendEventListener} 的单元测试：去重 / 空短路 / 单条失败不中断。
 */
class NotifySendEventListenerTest extends BaseMockitoUnitTest {

    @InjectMocks
    private NotifySendEventListener listener;

    @Mock
    private NotifyMessageSendApi notifyMessageSendApi;

    @Test
    void testOnNotifySend_dedupAndSend() {
        // 1L 重复两次 + 2L：去重后只发 1L、2L 各一次
        listener.onNotifySend(NotifySendEvent.of(Arrays.asList(1L, 1L, 2L), "task_assigned", new HashMap<>()));
        verify(notifyMessageSendApi, times(1)).sendSingleNotifyToAdmin(eq(1L), eq("task_assigned"), any(), eq(NotifyMessageLevelConstants.NORMAL));
        verify(notifyMessageSendApi, times(1)).sendSingleNotifyToAdmin(eq(2L), eq("task_assigned"), any(), eq(NotifyMessageLevelConstants.NORMAL));
    }

    @Test
    void testOnNotifySend_emptyRecipients_noSend() {
        listener.onNotifySend(NotifySendEvent.of(Collections.emptyList(), "task_assigned", new HashMap<>()));
        verify(notifyMessageSendApi, times(0)).sendSingleNotifyToAdmin(any(), any(), any(), any());
    }

    @Test
    void testOnNotifySend_singleFailure_doesNotInterrupt() {
        // 第一个人发送抛异常，第二个人仍应被发送（兜底不中断）
        doThrow(new RuntimeException("boom")).when(notifyMessageSendApi)
                .sendSingleNotifyToAdmin(eq(1L), any(), any(), any());
        listener.onNotifySend(NotifySendEvent.of(Arrays.asList(1L, 2L), "task_assigned", new HashMap<>()));
        verify(notifyMessageSendApi, times(1)).sendSingleNotifyToAdmin(eq(2L), any(), any(), any());
    }

    @Test
    void testOnNotifySend_excludesOperator() {
        // userIds 含操作人 1L 与 2L；operatorUserId=1L
        listener.onNotifySend(NotifySendEvent.of(
                Arrays.asList(1L, 2L), "task_assigned", new HashMap<>(),
                NotifyMessageLevelConstants.NORMAL, 1L));
        // 1L 是操作人，应被排除；仅 2L 收到，且五参工厂的 level 应原样透传
        verify(notifyMessageSendApi, times(0))
                .sendSingleNotifyToAdmin(eq(1L), any(), any(), any());
        verify(notifyMessageSendApi, times(1))
                .sendSingleNotifyToAdmin(eq(2L), eq("task_assigned"), any(), eq(NotifyMessageLevelConstants.NORMAL));
    }
}
