/**
 * Notification Handler - Push Notifications and Periodic Notifications API
 * Handles user notifications and keeps users informed of app events
 */

class NotificationHandler {
  constructor() {
    this.serviceWorkerReady = false;
    this.subscriptionReady = false;
    this.pollingInterval = null;

    this.init();
  }

  /**
   * Initialize notification handler
   */
  async init() {
    console.log('[NotificationHandler] Initializing...');

    // Wait for service worker
    this.waitForServiceWorker();

    // Setup notification click handling
    this.setupNotificationHandling();

    console.log('[NotificationHandler] Initialized');
  }

  /**
   * Wait for Service Worker to be ready
   */
  waitForServiceWorker() {
    if (!('serviceWorker' in navigator)) {
      console.warn('[NotificationHandler] Service Worker not supported');
      return;
    }

    navigator.serviceWorker.ready.then(() => {
      console.log('[NotificationHandler] Service Worker is ready');
      this.serviceWorkerReady = true;

      // Setup push notifications if PWA helper is available
      if (window.pwaHelper) {
        this.setupPushNotifications();
      }
    });
  }

  /**
   * Setup push notifications
   */
  async setupPushNotifications() {
    if (!this.serviceWorkerReady) {
      console.warn('[NotificationHandler] Service Worker not ready');
      return;
    }

    try {
      // Check if already subscribed
      const registration = await navigator.serviceWorker.ready;
      const subscription = await registration.pushManager.getSubscription();

      if (subscription) {
        console.log('[NotificationHandler] Already subscribed to push');
        this.subscriptionReady = true;
        return;
      }

      // Subscribe to push notifications
      console.log('[NotificationHandler] Setting up push notifications...');
      const pushSubscription = await window.pwaHelper.subscribeToPushNotifications();
      
      if (pushSubscription) {
        this.subscriptionReady = true;
        console.log('[NotificationHandler] Push notifications subscribed');
      }
    } catch (error) {
      console.error('[NotificationHandler] Error setting up push:', error);
    }
  }

  /**
   * Setup notification click handling
   */
  setupNotificationHandling() {
    // Handle notifications clicked by user
    if ('Notification' in window) {
      // Notification clicks are handled in service worker
      console.log('[NotificationHandler] Notification click handling ready');
    }
  }

  /**
   * Show local notification
   */
  async showNotification(title, options = {}) {
    try {
      if (!('Notification' in window)) {
        console.warn('[NotificationHandler] Notifications not supported');
        return false;
      }

      const permission = await this.ensurePermission();
      if (permission !== 'granted') {
        console.warn('[NotificationHandler] Notification permission not granted');
        return false;
      }

      const registration = await navigator.serviceWorker.ready;
      await registration.showNotification(title, {
        icon: '/invcount/assets/images/icons/icon-192x192.png',
        badge: '/invcount/assets/images/icons/badge-72x72.png',
        ...options,
      });

      console.log('[NotificationHandler] Notification shown:', title);
      return true;
    } catch (error) {
      console.error('[NotificationHandler] Error showing notification:', error);
      return false;
    }
  }

  /**
   * Request notification permission if needed
   */
  async ensurePermission() {
    if (!('Notification' in window)) {
      return 'denied';
    }

    if (Notification.permission === 'granted') {
      return 'granted';
    }

    if (Notification.permission !== 'default') {
      return Notification.permission;
    }

    // Request permission
    const permission = await Notification.requestPermission();
    return permission;
  }

  /**
   * Notify count submission
   */
  async notifyCountSubmitted(itemName, quantity) {
    return this.showNotification(`Count Submitted`, {
      body: `${itemName}: ${quantity} units`,
      tag: 'count-submitted',
      requireInteraction: false,
    });
  }

  /**
   * Notify assignment update
   */
  async notifyAssignmentUpdate(assignment) {
    return this.showNotification(`New Assignment`, {
      body: assignment.description || 'You have a new assignment',
      tag: 'assignment-update',
      data: {
        url: '/invcount/counter/my_assignments.php',
      },
      requireInteraction: true,
    });
  }

  /**
   * Notify sync completion
   */
  async notifySyncComplete(itemCount) {
    return this.showNotification(`Sync Complete`, {
      body: `${itemCount} items synchronized`,
      tag: 'sync-complete',
      requireInteraction: false,
    });
  }

  /**
   * Notify sync error
   */
  async notifySyncError(errorMessage) {
    return this.showNotification(`Sync Failed`, {
      body: errorMessage || 'Data synchronization failed',
      tag: 'sync-error',
      requireInteraction: true,
    });
  }

  /**
   * Notify report ready
   */
  async notifyReportReady(reportTitle) {
    return this.showNotification(`Report Ready`, {
      body: reportTitle || 'Your report is ready to download',
      tag: 'report-ready',
      requireInteraction: true,
      data: {
        url: '/invcount/admin/reports.php',
      },
    });
  }

  /**
   * Setup periodic notification polling (fallback for older browsers)
   */
  setupPeriodicNotifications(intervalMs = 5 * 60 * 1000) {
    if (this.pollingInterval) {
      clearInterval(this.pollingInterval);
    }

    console.log('[NotificationHandler] Starting periodic notification polling');
    
    this.pollingInterval = setInterval(() => {
      this.checkForNotifications();
    }, intervalMs);
  }

  /**
   * Check server for notifications
   */
  async checkForNotifications() {
    try {
      const response = await fetch('/invcount/api/get-notifications');
      if (!response.ok) return;

      const notifications = await response.json();
      
      for (const notif of notifications) {
        await this.showNotification(notif.title, {
          body: notif.body,
          tag: notif.tag || 'server-notification',
          requireInteraction: notif.requireInteraction || false,
          data: notif.data || {},
        });
      }
    } catch (error) {
      console.error('[NotificationHandler] Error checking notifications:', error);
    }
  }

  /**
   * Stop periodic notification polling
   */
  stopPeriodicNotifications() {
    if (this.pollingInterval) {
      clearInterval(this.pollingInterval);
      this.pollingInterval = null;
      console.log('[NotificationHandler] Periodic notification polling stopped');
    }
  }

  /**
   * Get notification status
   */
  getStatus() {
    return {
      serviceWorkerReady: this.serviceWorkerReady,
      subscriptionReady: this.subscriptionReady,
      pollingActive: !!this.pollingInterval,
      permissionStatus: 'Notification' in window ? Notification.permission : 'unsupported',
    };
  }

  /**
   * Cleanup
   */
  destroy() {
    this.stopPeriodicNotifications();
    console.log('[NotificationHandler] Destroyed');
  }
}

// Initialize Notification Handler when DOM is ready
if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', () => {
    window.notificationHandler = new NotificationHandler();
  });
} else {
  window.notificationHandler = new NotificationHandler();
}
