// src/services/push.service.js
const webpush = require('web-push');
const config = require('../config');
const pushRepo = require('../repositories/push.repo');

const hasVapid = !!config.vapid.publicKey && !!config.vapid.privateKey;

if (!hasVapid) {
  console.warn('[Push] VAPID keys não definidas. Push desativado.');
} else {
  webpush.setVapidDetails(config.vapid.subject, config.vapid.publicKey, config.vapid.privateKey);
}

async function sendWithRetry(subscription, message, tries = 2) {
  try {
    return await webpush.sendNotification(subscription, message);
  } catch (err) {
    const code = err?.statusCode;
    if ((code === 429 || code >= 500) && tries > 1) {
      await new Promise((r) => setTimeout(r, 1000));
      return sendWithRetry(subscription, message, tries - 1);
    }
    throw err;
  }
}

async function sendPushToUser(userId, payload) {
  if (!hasVapid) return;

  const subs = await pushRepo.listByUser(userId);
  if (!subs.length) return;

  const message = JSON.stringify(payload);

  await Promise.allSettled(
    subs.map(async (s) => {
      const subscription = {
        endpoint: s.endpoint,
        keys: { p256dh: s.p256dh, auth: s.auth },
      };

      try {
        await sendWithRetry(subscription, message);
      } catch (err) {
        const code = err?.statusCode;
        if (code === 404 || code === 410) {
          await pushRepo.deleteById(s.id);
        } else {
          console.error('[Push] erro ao enviar:', err.message);
        }
      }
    })
  );
}

module.exports = { sendPushToUser };
