/* Hostiva V4 Real-time — SSE + polling fallback, optimised */
(function () {
  if (!window.HOSTIVA || !window.api) return;

  let lastEventId = parseInt(localStorage.getItem('hv4_last_event') || '0', 10);
  let pollTimer   = null;
  let sseConn     = null;
  let backoff     = 12000; // start at 12s, doubles on error, caps at 60s

  // ── Notification badge — uses cached count, only fetches on demand ────────
  let _unreadCount = 0;

  async function fetchUnread() {
    try {
      const notifs = await api('notifications');
      _unreadCount = Array.isArray(notifs) ? notifs.filter(n => !n.read_at).length : 0;
    } catch { /* silent */ }
    renderBadge();
  }

  function renderBadge() {
    const bell = document.getElementById('hv4-notify-badge');
    if (!bell) return;
    bell.textContent = _unreadCount > 99 ? '99+' : String(_unreadCount);
    bell.style.display = _unreadCount > 0 ? 'inline-block' : 'none';
  }

  // ── Event handler ─────────────────────────────────────────────────────────
  function handleEvents(events) {
    if (!Array.isArray(events) || !events.length) return;
    let hasNew = false;
    events.forEach(ev => {
      const id = parseInt(String(ev.id || 0).replace(/\D/g, ''), 10) || 0;
      if (id > lastEventId) { lastEventId = id; hasNew = true; }
      document.dispatchEvent(new CustomEvent('hostiva:event', { detail: ev }));

      const p = ev.payload || {};
      if (ev.event_type === 'guest.request') {
        _unreadCount++;
        renderBadge();
        toast('🔔 Guest request: ' + (p.service || 'new request'), 'info');
      } else if (ev.event_type === 'report.submitted') {
        _unreadCount++;
        renderBadge();
        toast('📋 New report submitted — review required', 'info');
      } else if (ev.event_type === 'alert') {
        toast((p.level === 'critical' ? '🚨 ' : '⚠️ ') + (p.message || 'Alert'), 'error', 6000);
      }
    });
    if (hasNew) localStorage.setItem('hv4_last_event', String(lastEventId));
  }

  // ── Polling ───────────────────────────────────────────────────────────────
  async function poll() {
    try {
      const events = await api('realtime/poll', { query: { since: lastEventId } });
      handleEvents(events);
      backoff = 12000; // reset on success
    } catch { /* silent */ }
  }

  function startPoll() {
    if (pollTimer) return;
    poll();
    pollTimer = setInterval(poll, backoff);
  }

  // ── SSE ───────────────────────────────────────────────────────────────────
  function startSSE() {
    if (typeof EventSource === 'undefined') { startPoll(); return; }
    if (sseConn && sseConn.readyState < 2) return; // already open/connecting
    if (sseConn) sseConn.close();
    try {
      const base = HOSTIVA.API || HOSTIVA.apiPhp;
      const url  = base + (base.includes('?') ? '&' : '?') + 'r=realtime/stream&since=' + lastEventId;
      sseConn = new EventSource(url, { withCredentials: true });
      sseConn.onmessage = e => { try { handleEvents([JSON.parse(e.data)]); } catch {} };
      sseConn.onerror = () => {
        sseConn?.close(); sseConn = null;
        backoff = Math.min(backoff * 2, 60000);
        if (!pollTimer) { pollTimer = setInterval(poll, backoff); }
      };
    } catch { startPoll(); }
  }

  // ── Init ─────────────────────────────────────────────────────────────────
  function init() {
    startSSE();
    fetchUnread(); // initial badge count
    // Refresh badge every 2 minutes (not every 12s)
    setInterval(fetchUnread, 120000);
  }

  document.addEventListener('hostiva:ready', init, { once: true });
  if (window.HOSTIVA.ready) init();

  window.HV4 = { poll, lastEventId: () => lastEventId, refreshBadge: fetchUnread };
})();
