/**
 * Modul: Erinnerungen (Reminders)
 * Zweck: Clientseitiges Polling für fällige Erinnerungen, Browser-Benachrichtigungen,
 *        In-App-Toasts und Bell-Badge-Aktualisierung.
 * Abhängigkeiten: /api.js, /i18n.js
 */

import { api } from '/api.js';
import { t } from '/i18n.js';

// --------------------------------------------------------
// Konfiguration
// --------------------------------------------------------

const POLL_INTERVAL_MS = 60_000; // 1 Minute

// --------------------------------------------------------
// Zustand
// --------------------------------------------------------

let _pollTimer     = null;
let _shownIds      = new Set(); // bereits angezeigte Reminder-IDs in dieser Session
let _isInitialized = false;

// --------------------------------------------------------
// Browser-Benachrichtigungen
// --------------------------------------------------------

/**
 * Aktuellen Benachrichtigungs-Permission-Status zurückgeben.
 * @returns {'granted'|'denied'|'default'|'unsupported'}
 */
function notificationStatus() {
  if (!('Notification' in window)) return 'unsupported';
  return Notification.permission;
}

/**
 * Browser-Benachrichtigung anfordern.
 * @returns {Promise<'granted'|'denied'|'default'>}
 */
async function requestPermission() {
  if (!('Notification' in window)) return 'unsupported';
  if (Notification.permission === 'granted') return 'granted';
  return Notification.requestPermission();
}

/**
 * Zeigt eine native Browser-Benachrichtigung an.
 * @param {string} title
 * @param {string} body
 */
function showBrowserNotification(title, body) {
  if (!('Notification' in window) || Notification.permission !== 'granted') return;
  try {
    const n = new Notification(title, { body, icon: '/icons/icon-192.png' });
    setTimeout(() => n.close(), 8000);
  } catch {
    // Notification-API kann in bestimmten Kontexten fehlschlagen
  }
}

// --------------------------------------------------------
// Bell-Badge (Sidebar / Bottom-Nav)
// --------------------------------------------------------

/**
 * Aktualisiert den Badge-Zähler am Bell-Icon in der Navigation.
 * @param {number} count
 */
function updateBellBadge(count) {
  const navLabel = count > 0
    ? t(count === 1 ? 'reminders.pendingBadgeTitle' : 'reminders.pendingBadgeTitlePlural', { count })
    : t('nav.reminders');
  document.querySelectorAll('[data-route="/reminders"]').forEach((navItem) => {
    navItem.setAttribute('aria-label', navLabel);
  });
  document.querySelectorAll('.reminder-bell-badge').forEach((badge) => {
    if (count > 0) {
      badge.setAttribute('aria-hidden', 'true');
      badge.textContent = count > 9 ? '9+' : String(count);
      badge.hidden = false;
    } else {
      badge.hidden = true;
    }
  });
}

// --------------------------------------------------------
// SVG-Helfer (DOM-API, kein innerHTML)
// --------------------------------------------------------

function createBellSvg() {
  const NS  = 'http://www.w3.org/2000/svg';
  const svg = document.createElementNS(NS, 'svg');
  svg.setAttribute('viewBox', '0 0 24 24');
  svg.setAttribute('fill', 'none');
  svg.setAttribute('stroke', 'currentColor');
  svg.setAttribute('stroke-width', '2');
  svg.setAttribute('width', '16');
  svg.setAttribute('height', '16');
  svg.setAttribute('aria-hidden', 'true');

  const path1 = document.createElementNS(NS, 'path');
  path1.setAttribute('d', 'M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9');
  const path2 = document.createElementNS(NS, 'path');
  path2.setAttribute('d', 'M13.73 21a2 2 0 0 1-3.46 0');

  svg.appendChild(path1);
  svg.appendChild(path2);
  return svg;
}

// --------------------------------------------------------
// Erinnerungen anzeigen
// --------------------------------------------------------

/**
 * Verarbeitet eine Liste fälliger Erinnerungen und zeigt Toast + Browser-Notification.
 * @param {Array} reminders
 */
function processReminders(reminders) {
  const newOnes = reminders.filter((r) => !_shownIds.has(r.id));
  if (!newOnes.length) return;

  newOnes.forEach((reminder) => {
    _shownIds.add(reminder.id);
    showReminderToast(reminder);
    showBrowserNotification(
      t('reminders.toastTitle'),
      reminder.entity_title || ''
    );
  });
}

/**
 * Zeigt einen persistenten Toast für eine Erinnerung mit Verwerfen-Button.
 * @param {{ id: number, entity_title: string }} reminder
 */
function showReminderToast(reminder) {
  const container = document.getElementById('toast-container');
  if (!container) return;

  const existing = container.querySelectorAll('.toast');
  if (existing.length >= 3) existing[0].remove();

  const toast = document.createElement('div');
  toast.className = 'toast toast--reminder';
  toast.setAttribute('role', 'alert');
  toast.dataset.reminderId = reminder.id;

  const iconWrap = document.createElement('span');
  iconWrap.className = 'toast__reminder-icon';
  iconWrap.setAttribute('aria-hidden', 'true');
  iconWrap.appendChild(createBellSvg());

  const textSpan = document.createElement('span');
  textSpan.className = 'toast__reminder-text';

  const titleEl = document.createElement('strong');
  titleEl.textContent = t('reminders.toastTitle');

  const sep = document.createTextNode(': ');

  const bodyEl = document.createElement('span');
  bodyEl.textContent = reminder.entity_title || '';

  textSpan.appendChild(titleEl);
  textSpan.appendChild(sep);
  textSpan.appendChild(bodyEl);

  const dismissBtn = document.createElement('button');
  dismissBtn.className = 'toast__undo';
  dismissBtn.textContent = t('reminders.dismiss');
  dismissBtn.addEventListener('click', () => {
    dismissReminder(reminder.id);
    toast.remove();
  });

  toast.appendChild(iconWrap);
  toast.appendChild(textSpan);
  toast.appendChild(dismissBtn);
  container.appendChild(toast);

  // Reminder-Toasts bleiben 30 Sekunden sichtbar
  const dismissTimer = setTimeout(() => {
    toast.classList.add('toast--out');
    toast.addEventListener('animationend', () => toast.remove(), { once: true });
  }, 30_000);

  toast.addEventListener('click', (e) => {
    if (e.target === dismissBtn) return;
    clearTimeout(dismissTimer);
    dismissReminder(reminder.id);
    toast.remove();
  });
}

// --------------------------------------------------------
// API-Aktionen
// --------------------------------------------------------

/**
 * Verwirft eine Erinnerung serverseitig.
 * @param {number} id
 */
async function dismissReminder(id) {
  try {
    await api.patch(`/reminders/${id}/dismiss`, {});
    _shownIds.delete(id);
  } catch {
    // Netzwerkfehler ignorieren
  }
}

/**
 * Lädt fällige Erinnerungen vom Server und verarbeitet sie.
 */
async function poll() {
  try {
    const data = await api.get('/reminders/pending');
    const reminders = data.data ?? [];
    updateBellBadge(reminders.length);
    processReminders(reminders);
  } catch {
    // Polling-Fehler ignorieren (kann Offline-Zustand sein)
  }
}

// --------------------------------------------------------
// Öffentliche API
// --------------------------------------------------------

/**
 * Startet das Reminder-Polling. Idempotent.
 */
function init() {
  if (_isInitialized) return;
  _isInitialized = true;
  poll();
  _pollTimer = setInterval(poll, POLL_INTERVAL_MS);
}

/**
 * Stoppt das Polling (z.B. nach Logout).
 */
function stop() {
  if (_pollTimer) {
    clearInterval(_pollTimer);
    _pollTimer = null;
  }
  _isInitialized = false;
  _shownIds.clear();
  updateBellBadge(0);
}

/**
 * Erzwingt sofortigen Poll (z.B. nach Erstellen einer Erinnerung).
 */
function refresh() {
  poll();
}

export { init, stop, refresh, requestPermission, notificationStatus };
