/**
 * TASKMATE - Notification Manager
 * ================================
 * Frontend-Verwaltung für das Benachrichtigungssystem
 */

import api from './api.js';
import store from './store.js';

class NotificationManager {
  constructor() {
    this.notifications = [];
    this.unreadCount = 0;
    this.isDropdownOpen = false;
    this.initialized = false;
  }

  /**
   * Initialisierung
   */
  async init() {
    if (this.initialized) return;

    this.bindElements();
    this.bindEvents();
    await this.loadNotifications();

    this.initialized = true;
  }

  /**
   * DOM-Elemente binden
   */
  bindElements() {
    this.bellBtn = document.getElementById('notification-btn');
    this.badge = document.getElementById('notification-badge');
    this.dropdown = document.getElementById('notification-dropdown');
    this.list = document.getElementById('notification-list');
    this.emptyState = document.getElementById('notification-empty');
    this.markAllBtn = document.getElementById('btn-mark-all-read');
    this.bellContainer = document.getElementById('notification-bell');
  }

  /**
   * Event-Listener binden
   */
  bindEvents() {
    // Toggle Dropdown
    this.bellBtn?.addEventListener('click', (e) => {
      e.stopPropagation();
      this.toggleDropdown();
    });

    // Klick außerhalb schließt Dropdown
    document.addEventListener('click', (e) => {
      if (!this.bellContainer?.contains(e.target)) {
        this.closeDropdown();
      }
    });

    // Alle als gelesen markieren
    this.markAllBtn?.addEventListener('click', (e) => {
      e.stopPropagation();
      this.markAllAsRead();
    });

    // Klicks in der Liste
    this.list?.addEventListener('click', (e) => {
      const deleteBtn = e.target.closest('.notification-delete');
      if (deleteBtn) {
        e.stopPropagation();
        const id = parseInt(deleteBtn.dataset.delete);
        this.deleteNotification(id);
        return;
      }

      const item = e.target.closest('.notification-item');
      if (item) {
        this.handleItemClick(item);
      }
    });

    // WebSocket Events
    window.addEventListener('notification:new', (e) => {
      this.addNotification(e.detail.notification);
    });

    window.addEventListener('notification:count', (e) => {
      this.updateBadge(e.detail.count);
    });

    window.addEventListener('notification:deleted', (e) => {
      this.removeNotification(e.detail.notificationId);
    });
  }

  /**
   * Benachrichtigungen vom Server laden
   */
  async loadNotifications() {
    try {
      const data = await api.getNotifications();
      this.notifications = data.notifications || [];
      this.unreadCount = data.unreadCount || 0;
      this.render();
    } catch (error) {
      console.error('Fehler beim Laden der Benachrichtigungen:', error);
    }
  }

  /**
   * Alles rendern
   */
  render() {
    this.updateBadge(this.unreadCount);
    this.renderList();
  }

  /**
   * Badge aktualisieren
   */
  updateBadge(count) {
    this.unreadCount = count;

    // Sicherstellen, dass badge-Element existiert
    if (!this.badge) {
      this.badge = document.getElementById('notification-badge');
    }

    if (!this.badge) return; // Wenn immer noch nicht gefunden, abbrechen

    if (count > 0) {
      this.badge.textContent = count > 99 ? '99+' : count;
      this.badge.classList.remove('hidden');
      this.bellContainer?.classList.add('has-notifications');
    } else {
      this.badge.classList.add('hidden');
      this.bellContainer?.classList.remove('has-notifications');
    }
  }

  /**
   * Liste rendern
   */
  renderList() {
    if (!this.notifications || this.notifications.length === 0) {
      this.list?.classList.add('hidden');
      this.emptyState?.classList.remove('hidden');
      return;
    }

    this.list?.classList.remove('hidden');
    this.emptyState?.classList.add('hidden');

    this.list.innerHTML = this.notifications.map(n => this.renderItem(n)).join('');
  }

  /**
   * Einzelnes Item rendern
   */
  renderItem(notification) {
    const timeAgo = this.formatTimeAgo(notification.createdAt);
    const iconClass = this.getIconClass(notification.type);
    const icon = this.getIcon(notification.type);

    return `
      <div class="notification-item ${notification.isRead ? '' : 'unread'} ${notification.isPersistent ? 'persistent' : ''}"
           data-id="${notification.id}"
           data-task-id="${notification.taskId || ''}"
           data-proposal-id="${notification.proposalId || ''}"
           data-entry-id="${notification.entryId || ''}"
           data-category-id="${notification.categoryId || ''}">
        <div class="notification-type-icon ${iconClass}">
          ${icon}
        </div>
        <div class="notification-content">
          <div class="notification-title">${this.escapeHtml(notification.title)}</div>
          ${notification.message ? `<div class="notification-message">${this.escapeHtml(notification.message)}</div>` : ''}
          <div class="notification-time">${timeAgo}</div>
        </div>
        ${!notification.isPersistent ? `
          <div class="notification-actions">
            <button class="notification-delete" title="Löschen" data-delete="${notification.id}">
              <svg viewBox="0 0 24 24"><path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
            </button>
          </div>
        ` : ''}
      </div>
    `;
  }

  /**
   * Icon-Klasse basierend auf Typ
   */
  getIconClass(type) {
    if (type.startsWith('task:assigned') || type.startsWith('task:unassigned') || type.startsWith('task:due')) {
      return 'task';
    }
    if (type.startsWith('task:completed')) {
      return 'completed';
    }
    if (type.startsWith('task:priority')) {
      return 'priority';
    }
    if (type.startsWith('comment:mention')) {
      return 'mention';
    }
    if (type.startsWith('comment:')) {
      return 'comment';
    }
    if (type.startsWith('approval:')) {
      return 'approval';
    }
    if (type.startsWith('knowledge:')) {
      return 'knowledge';
    }
    return 'task';
  }

  /**
   * Icon SVG basierend auf Typ
   */
  getIcon(type) {
    if (type.startsWith('task:assigned')) {
      return '<svg viewBox="0 0 24 24"><path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" stroke="currentColor" stroke-width="2" fill="none"/><circle cx="8.5" cy="7" r="4" stroke="currentColor" stroke-width="2" fill="none"/><path d="M20 8v6M23 11h-6" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>';
    }
    if (type.startsWith('task:unassigned')) {
      return '<svg viewBox="0 0 24 24"><path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" stroke="currentColor" stroke-width="2" fill="none"/><circle cx="8.5" cy="7" r="4" stroke="currentColor" stroke-width="2" fill="none"/><path d="M23 11h-6" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>';
    }
    if (type.startsWith('task:completed')) {
      return '<svg viewBox="0 0 24 24"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" stroke="currentColor" stroke-width="2" fill="none"/><path d="M22 4 12 14.01l-3-3" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>';
    }
    if (type.startsWith('task:due')) {
      return '<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none"/><path d="M12 6v6l4 2" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>';
    }
    if (type.startsWith('task:priority')) {
      return '<svg viewBox="0 0 24 24"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" stroke="currentColor" stroke-width="2" fill="none"/><path d="M12 9v4M12 17h.01" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>';
    }
    if (type.startsWith('comment:mention')) {
      return '<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="4" stroke="currentColor" stroke-width="2" fill="none"/><path d="M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-3.92 7.94" stroke="currentColor" stroke-width="2" fill="none"/></svg>';
    }
    if (type.startsWith('comment:')) {
      return '<svg viewBox="0 0 24 24"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" stroke="currentColor" stroke-width="2" fill="none"/></svg>';
    }
    if (type.startsWith('approval:pending')) {
      return '<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none"/><path d="M12 8v4M12 16h.01" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>';
    }
    if (type.startsWith('approval:granted')) {
      return '<svg viewBox="0 0 24 24"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" stroke="currentColor" stroke-width="2" fill="none"/><path d="M22 4 12 14.01l-3-3" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>';
    }
    if (type.startsWith('approval:rejected')) {
      return '<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none"/><path d="M15 9l-6 6M9 9l6 6" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>';
    }
    if (type.startsWith('knowledge:')) {
      return '<svg viewBox="0 0 24 24"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" stroke="currentColor" stroke-width="2" fill="none" stroke-linejoin="round"/></svg>';
    }
    // Default
    return '<svg viewBox="0 0 24 24"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9" stroke="currentColor" stroke-width="2" fill="none"/></svg>';
  }

  /**
   * Zeit-Formatierung
   */
  formatTimeAgo(dateString) {
    const date = new Date(dateString);
    const now = new Date();
    const diffMs = now - date;
    const diffMins = Math.floor(diffMs / 60000);
    const diffHours = Math.floor(diffMs / 3600000);
    const diffDays = Math.floor(diffMs / 86400000);

    if (diffMins < 1) return 'Gerade eben';
    if (diffMins < 60) return `Vor ${diffMins} Minute${diffMins === 1 ? '' : 'n'}`;
    if (diffHours < 24) return `Vor ${diffHours} Stunde${diffHours === 1 ? '' : 'n'}`;
    if (diffDays < 7) return `Vor ${diffDays} Tag${diffDays === 1 ? '' : 'en'}`;

    return date.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' });
  }

  /**
   * HTML escapen
   */
  escapeHtml(text) {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
  }

  /**
   * Dropdown öffnen/schließen
   */
  toggleDropdown() {
    if (this.isDropdownOpen) {
      this.closeDropdown();
    } else {
      this.openDropdown();
    }
  }

  openDropdown() {
    this.dropdown?.classList.remove('hidden');
    this.isDropdownOpen = true;
    // Ungelesene als gelesen markieren wenn Dropdown geöffnet
    this.markVisibleAsRead();
  }

  closeDropdown() {
    this.dropdown?.classList.add('hidden');
    this.isDropdownOpen = false;
  }

  /**
   * Sichtbare Benachrichtigungen als gelesen markieren
   */
  async markVisibleAsRead() {
    const unreadItems = this.notifications.filter(n => !n.isRead && !n.isPersistent);

    for (const notification of unreadItems) {
      try {
        await api.markNotificationRead(notification.id);
        notification.isRead = true;
      } catch (error) {
        console.error('Fehler beim Markieren als gelesen:', error);
      }
    }

    this.renderList();
  }

  /**
   * Alle als gelesen markieren
   */
  async markAllAsRead() {
    try {
      await api.markAllNotificationsRead();
      this.notifications.forEach(n => {
        if (!n.isPersistent) n.isRead = true;
      });
      this.unreadCount = this.notifications.filter(n => !n.isRead).length;
      this.updateBadge(this.unreadCount);
      this.renderList();
    } catch (error) {
      console.error('Fehler beim Markieren aller als gelesen:', error);
    }
  }

  /**
   * Benachrichtigung löschen
   */
  async deleteNotification(id) {
    try {
      const result = await api.deleteNotification(id);
      this.notifications = this.notifications.filter(n => n.id !== id);
      this.unreadCount = result.unreadCount;
      this.updateBadge(this.unreadCount);
      this.renderList();
    } catch (error) {
      console.error('Fehler beim Löschen der Benachrichtigung:', error);
    }
  }

  /**
   * Neue Benachrichtigung hinzufügen
   */
  addNotification(notification) {
    // Am Anfang der Liste hinzufügen
    this.notifications.unshift(notification);
    this.unreadCount++;
    this.updateBadge(this.unreadCount);
    this.renderList();

    // Toast anzeigen wenn Dropdown geschlossen
    if (!this.isDropdownOpen) {
      this.showToast(notification.title, notification.message);
    }
  }

  /**
   * Benachrichtigung entfernen (WebSocket)
   */
  removeNotification(id) {
    this.notifications = this.notifications.filter(n => n.id !== id);
    this.renderList();
  }

  /**
   * Toast-Benachrichtigung anzeigen
   */
  showToast(title, message) {
    // Einfache Toast-Implementation
    const toast = document.createElement('div');
    toast.className = 'notification-toast';
    toast.innerHTML = `
      <strong>${this.escapeHtml(title)}</strong>
      ${message ? `<p>${this.escapeHtml(message)}</p>` : ''}
    `;
    toast.style.cssText = `
      position: fixed;
      bottom: 20px;
      right: 20px;
      padding: 16px 20px;
      background: var(--bg-card, #fff);
      border: 1px solid var(--border-default, #e2e8f0);
      border-radius: 8px;
      box-shadow: 0 10px 25px rgba(0,0,0,0.15);
      z-index: 9999;
      max-width: 320px;
      animation: slideIn 0.3s ease;
    `;

    // Animation
    const style = document.createElement('style');
    style.textContent = `
      @keyframes slideIn {
        from { transform: translateX(100%); opacity: 0; }
        to { transform: translateX(0); opacity: 1; }
      }
    `;
    document.head.appendChild(style);

    document.body.appendChild(toast);

    // Nach 4 Sekunden entfernen
    setTimeout(() => {
      toast.style.animation = 'slideIn 0.3s ease reverse';
      setTimeout(() => {
        toast.remove();
        style.remove();
      }, 300);
    }, 4000);
  }

  /**
   * Item-Klick behandeln
   */
  handleItemClick(item) {
    const taskId = item.dataset.taskId;
    const proposalId = item.dataset.proposalId;
    const entryId = item.dataset.entryId;
    const categoryId = item.dataset.categoryId;

    if (taskId) {
      // Zur Aufgabe navigieren
      this.closeDropdown();
      window.dispatchEvent(new CustomEvent('notification:open-task', { detail: { taskId: parseInt(taskId) } }));
    } else if (proposalId) {
      // Zum Genehmigung-Tab wechseln
      this.closeDropdown();
      window.dispatchEvent(new CustomEvent('notification:open-proposal', { detail: { proposalId: parseInt(proposalId) } }));
    } else if (entryId && categoryId) {
      // Zum Wissenseintrag navigieren
      this.closeDropdown();
      window.dispatchEvent(new CustomEvent('notification:open-knowledge', { detail: { 
        entryId: parseInt(entryId),
        categoryId: parseInt(categoryId)
      }}));
    }
  }

  /**
   * Reset
   */
  reset() {
    this.notifications = [];
    this.unreadCount = 0;
    this.isDropdownOpen = false;
    this.closeDropdown();
    
    // Elements neu binden falls nötig
    if (!this.badge || !this.bellContainer) {
      this.bindElements();
    }
    
    this.render();
  }
}

// Singleton-Instanz
const notificationManager = new NotificationManager();

export { notificationManager };
export default notificationManager;
