package com.ga.api.service.push;

import com.ga.common.adapter.push.PushAdapter;
import com.ga.common.adapter.push.PushRequest;
import com.ga.core.mapper.notice.UserDeviceTokenMapper;
import com.ga.core.vo.notice.UserDeviceTokenVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 사용자 단위 푸시 디스패치.
 * <p>
 * user_notification 발행 지점에서 호출해, 해당 사용자의 활성 디바이스 토큰 전부에 best-effort 푸시.
 * 푸시 실패가 본 트랜잭션(알림 발행/정산)을 깨지 않도록 모든 예외를 흡수한다.
 * 실제 발송은 {@link PushAdapter} 구현(mock/fcm, app.adapter.push)로 위임.
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class PushDispatchService {

    private final PushAdapter pushAdapter;
    private final UserDeviceTokenMapper deviceTokenMapper;

    /** 사용자의 모든 활성 디바이스에 푸시 (best-effort). */
    public void sendToUser(Long userId, String title, String body, String refType, Long refId) {
        if (userId == null) return;
        try {
            List<UserDeviceTokenVO> tokens = deviceTokenMapper.selectActiveByUser(userId);
            for (UserDeviceTokenVO t : tokens) {
                try {
                    pushAdapter.send(PushRequest.builder()
                            .deviceToken(t.getToken())
                            .title(title)
                            .body(body)
                            .refType(refType)
                            .refId(refId)
                            .refUserId(userId)
                            .build());
                } catch (Exception e) {
                    log.warn("[PUSH] 발송 실패 userId={} tokenId={}: {}", userId, t.getTokenId(), e.getMessage());
                }
            }
        } catch (Exception e) {
            log.warn("[PUSH] 디스패치 실패 userId={}: {}", userId, e.getMessage());
        }
    }
}
