// utils/pushService.js
const webpush = require('web-push');
const db = require('../db');

const hasVapid =
  !!process.env.VAPID_PUBLIC_KEY && !!process.env.VAPID_PRIVATE_KEY;

if (!hasVapid) {
  console.warn('[Push] VAPID keys não definidas. Push desativado.');
} else {
  webpush.setVapidDetails(
    process.env.VAPID_SUBJECT || 'mailto:admin@evstation.local',
    process.env.VAPID_PUBLIC_KEY,
    process.env.VAPID_PRIVATE_KEY
  );
}

// retry simples p/ 429 e 5xx
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 db('push_subscriptions')
    .where({ user_id: userId })
    .select('id', 'endpoint', 'p256dh', 'auth');

  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);

        // TTL opcional (default 15min)
        // se quiseres usar TTL do payload, descomenta e passa options no sendWithRetry
        // await webpush.sendNotification(subscription, message, {
        //   TTL: payload.ttl ?? 60 * 15,
        // });
      } catch (err) {
        const code = err?.statusCode;

        // remove subscriptions mortas
        if (code === 404 || code === 410) {
          await db('push_subscriptions').where({ id: s.id }).del();
        } else {
          console.error('[Push] erro ao enviar:', err.message);
        }
      }
    })
  );
}

module.exports = { sendPushToUser };
