import api from './api';

const VAPID_KEY = process.env.NEXT_PUBLIC_FIREBASE_VAPID_KEY;

class NotificationService {
  private currentToken: string | null = null;
  private messaging: any = null;

  private async getFirebaseMessaging() {
    if (this.messaging) return this.messaging;

    try {
      const { getMessaging, isSupported } = await import('firebase/messaging');
      const supported = await isSupported();
      if (!supported) {
        console.log('[Notifications] Firebase messaging not supported');
        return null;
      }

      const { initializeApp, getApps } = await import('firebase/app');
      const firebaseConfig = {
        apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
        authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
        projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
        storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
        messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
        appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
      };
      const app = getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0];
      this.messaging = getMessaging(app);
      return this.messaging;
    } catch (error) {
      console.error('[Notifications] Failed to init Firebase messaging:', error);
      return null;
    }
  }

  async requestPermissionAndRegister(): Promise<boolean> {
    try {
      if (typeof window === 'undefined') return false;

      if (!VAPID_KEY) {
        console.warn('[Notifications] VAPID key not configured');
        return false;
      }

      if (!('Notification' in window)) {
        console.log('[Notifications] Notifications API not available');
        return false;
      }

      if (!('serviceWorker' in navigator)) {
        console.log('[Notifications] Service workers not supported');
        return false;
      }

      const messaging = await this.getFirebaseMessaging();
      if (!messaging) return false;

      // Request notification permission
      const permission = await Notification.requestPermission();
      console.log('[Notifications] Permission:', permission);
      if (permission !== 'granted') {
        console.log('[Notifications] Permission denied');
        return false;
      }

      // Register service worker
      const registration = await navigator.serviceWorker.register(
        '/firebase-messaging-sw.js'
      );
      console.log('[Notifications] Service worker registered:', registration.scope);

      // Wait for service worker to be ready
      await navigator.serviceWorker.ready;

      // Get FCM token
      const { getToken } = await import('firebase/messaging');
      const token = await getToken(messaging, {
        vapidKey: VAPID_KEY,
        serviceWorkerRegistration: registration,
      });

      if (!token) {
        console.warn('[Notifications] No FCM token received');
        return false;
      }

      console.log('[Notifications] FCM token obtained:', token.substring(0, 20) + '...');
      this.currentToken = token;

      // Register token with backend
      await api.post('/notifications/fcm-token', {
        token,
        device: 'web',
      });

      console.log('[Notifications] FCM token registered with backend');
      return true;
    } catch (error) {
      console.error('[Notifications] Registration failed:', error);
      return false;
    }
  }

  async unregister(): Promise<void> {
    try {
      if (this.currentToken) {
        await api.delete('/notifications/fcm-token', {
          data: { token: this.currentToken },
        });
        this.currentToken = null;
      }
    } catch (error) {
      console.error('[Notifications] Unregister failed:', error);
    }
  }

  async setupForegroundHandler(
    callback: (payload: { title: string; body: string; data?: Record<string, string> }) => void
  ): Promise<(() => void) | null> {
    try {
      const messaging = await this.getFirebaseMessaging();
      if (!messaging) return null;

      const { onMessage } = await import('firebase/messaging');
      const unsubscribe = onMessage(messaging, (payload) => {
        console.log('[Notifications] Foreground message:', payload);
        callback({
          title: payload.notification?.title || 'New Notification',
          body: payload.notification?.body || '',
          data: payload.data as Record<string, string>,
        });
      });
      return unsubscribe;
    } catch (error) {
      console.error('[Notifications] Foreground handler failed:', error);
      return null;
    }
  }
}

export const notificationService = new NotificationService();
