(function () {
  'use strict';

  const bell = document.querySelector('[data-notification-bell]');
  if (!bell) return;

  const trigger = bell.querySelector('.notification-bell__trigger');
  const countEl = bell.querySelector('[data-unread-count]');
  const dropdown = bell.querySelector('[data-notification-dropdown]');
  if (!trigger || !countEl || !dropdown) return;
  let isOpen = false;

  trigger.addEventListener('click', (e) => {
    e.stopPropagation();
    isOpen = !isOpen;
    dropdown.hidden = !isOpen;
    trigger.setAttribute('aria-expanded', String(isOpen));
    if (isOpen) loadNotifications();
  });

  dropdown.addEventListener('click', (e) => {
    e.stopPropagation();
  });

  document.addEventListener('click', () => {
    if (isOpen) {
      isOpen = false;
      dropdown.hidden = true;
      trigger.setAttribute('aria-expanded', 'false');
    }
  });

  async function updateBell() {
    try {
      const res = await fetch('/api/notifications/bell');
      if (!res.ok) return;
      const data = await res.json();
      const count = data.unreadCount || 0;
      countEl.textContent = count > 99 ? '99+' : String(count);
      countEl.hidden = count === 0;
      bell.classList.toggle('has-unread', count > 0);
    } catch (err) {
      console.error('bell update', err);
    }
  }

  async function loadNotifications() {
    try {
      const res = await fetch('/api/notifications?limit=20');
      if (!res.ok) return;
      const data = await res.json();
      renderNotifications(data.notifications || []);
    } catch (err) {
      console.error('load notifications', err);
    }
  }

  function renderNotifications(notifications) {
    const list = dropdown.querySelector('ul');
    if (!list) return;
    list.innerHTML = '';

    // Header
    const header = document.createElement('li');
    header.className = 'notification-header';
    header.textContent = 'Notifications';
    list.appendChild(header);

    if (!notifications.length) {
      const empty = document.createElement('li');
      empty.className = 'notification-empty';
      empty.textContent = 'No notifications';
      list.appendChild(empty);
      return;
    }

    notifications.forEach(n => {
      const li = document.createElement('li');
      li.className = n.readAt ? 'notification-item is-read' : 'notification-item';
      const button = document.createElement('button');
      button.type = 'button';
      button.className = 'notification-item__button';
      button.innerHTML = `
        <div class="notification-message">${escapeHtml(n.message)}</div>
        <time class="notification-time">${formatDate(n.createdAt)}</time>
      `;
      button.addEventListener('click', async () => {
        if (!n.readAt) await markRead(n.id, false);
        const target = notificationURL(n);
        if (target) window.location.assign(target);
      });
      li.appendChild(button);
      list.appendChild(li);
    });

    // Add "Mark all read" button
    if (notifications.some(notification => !notification.readAt)) {
      const footer = document.createElement('li');
      footer.className = 'notification-footer';
      const btn = document.createElement('button');
      btn.textContent = 'Mark all read';
      btn.addEventListener('click', markAllRead);
      footer.appendChild(btn);
      list.appendChild(footer);
    }
  }

  async function markRead(id, refresh = true) {
    try {
      const response = await fetch(`/api/notifications/${encodeURIComponent(id)}/read`, { method: 'POST' });
      if (!response.ok) throw new Error(await response.text());
      if (refresh) {
        updateBell();
        loadNotifications();
      }
    } catch (err) {
      console.error('mark read', err);
    }
  }

  async function markAllRead() {
    try {
      const response = await fetch('/api/notifications/read-all', { method: 'POST' });
      if (!response.ok) throw new Error(await response.text());
      updateBell();
      loadNotifications();
    } catch (err) {
      console.error('mark all read', err);
    }
  }

  function escapeHtml(str) {
    const div = document.createElement('div');
    div.textContent = str;
    return div.innerHTML;
  }

  function formatDate(iso) {
    const d = new Date(iso);
    return d.toLocaleString();
  }

  function notificationURL(notification) {
    if (notification.resourceType !== 'document' || !notification.resourceId) return '';
    const path = notification.resourceId.replace(/^doc:/, '').split('/').map(encodeURIComponent).join('/');
    return '/docs/' + path;
  }

  // Listen for WebSocket notification events
  if (window.__cairnquireRealtime) {
    window.__cairnquireRealtime.on('notification', () => {
      updateBell();
    });
  }

  // Poll every 60s as fallback
  setInterval(updateBell, 60000);
  updateBell();
})();
