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

import com.njcn.rdms.module.system.api.notify.NotifyMessageSendApi;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;

import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;

/**
 * 站内信发送事件监听器（project 域统一入口，全局唯一）。
 *
 * <p>在业务事务提交后（AFTER_COMMIT）统一发送：接收人去重 + 空短路 + 逐人调用，
 * 单条失败 try-catch + log.warn，不抛出、不中断其余，绝不影响/回滚业务。</p>
 *
 * @author hongawen
 */
@Component
@Slf4j
public class NotifySendEventListener {

    @Resource
    private NotifyMessageSendApi notifyMessageSendApi;

    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
    public void onNotifySend(NotifySendEvent event) {
        if (event == null || event.getUserIds() == null) {
            return;
        }
        // 去重（保留首次出现顺序），过滤 null
        Set<Long> targets = new LinkedHashSet<>();
        for (Long userId : event.getUserIds()) {
            if (Objects.nonNull(userId)) {
                targets.add(userId);
            }
        }
        // 排除操作人：创建通知不发给操作人自己（operatorUserId 为 null 的存量场景不排除）
        if (event.getOperatorUserId() != null) {
            targets.remove(event.getOperatorUserId());
        }
        if (targets.isEmpty()) {
            return;
        }
        for (Long userId : targets) {
            try {
                notifyMessageSendApi.sendSingleNotifyToAdmin(userId, event.getTemplateCode(),
                        event.getParams(), event.getLevel());
            } catch (Exception ex) {
                // 通知失败不影响业务：仅告警，继续发其余接收人
                log.warn("[onNotifySend] 站内信发送失败 userId={}, templateCode={}",
                        userId, event.getTemplateCode(), ex);
            }
        }
    }

}
