// Outbound webhook delivery. emit(event, tenantId, payload) fans the event out to every
// active per-tenant subscription registered for that event, plus the legacy global
// BIZGAZE_WEBHOOK_URL (back-compat). Each delivery is HMAC-signed and retried on failure.
//
// NOTE (roadmap): retries are in-memory/best-effort. For guaranteed delivery this should
// move to a persistent queue when the app scales to multiple instances (see ARCHITECTURE.md).
const R = require('./repos');
const crypto = require('crypto');

const EVENTS = ['session.started', 'session.ended'];

function sign(secret, body) {
  return crypto.createHmac('sha256', secret || '').update(body).digest('base64url');
}

const RETRY_DELAYS = [2000, 10000, 30000]; // after the first attempt
function deliver(url, secret, body, onDone) {
  let attempt = 0;
  const go = async () => {
    attempt++;
    let ok = false, status = 0, err = null;
    try {
      const res = await fetch(url, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'X-BizGaze-Signature': sign(secret, body), 'X-BizGaze-Event': (() => { try { return JSON.parse(body).event; } catch { return ''; } })() },
        body,
        signal: AbortSignal.timeout(10000),
      });
      status = res.status; ok = res.ok;
    } catch (e) { err = (e && e.message) || 'delivery failed'; }
    if (ok || attempt > RETRY_DELAYS.length) { if (onDone) onDone({ ok, status, err }); return; }
    setTimeout(go, RETRY_DELAYS[attempt - 1]);
  };
  go();
}

async function emit(event, tenantId, payload) {
  const body = JSON.stringify({ event, ...payload });
  // Per-tenant subscriptions
  try {
    for (const h of await R.webhooks.activeForTenant(tenantId)) {
      const subs = String(h.events || '').split(',').map((s) => s.trim());
      if (subs.includes('*') || subs.includes(event)) {
        deliver(h.url, h.secret, body, async (r) => { try { await R.webhooks.setStatus(h.id, r.ok ? 1 : 0, r.err || ('HTTP ' + r.status)); } catch (_) {} });
      }
    }
  } catch (_) {}
  // Legacy global webhook (back-compat): session.ended → BIZGAZE_WEBHOOK_URL, signed with SSO_SECRET.
  if (event === 'session.ended' && process.env.BIZGAZE_WEBHOOK_URL) {
    deliver(process.env.BIZGAZE_WEBHOOK_URL, process.env.SSO_SECRET || '', body);
  }
}

module.exports = { emit, sign, EVENTS };
