'use client';

import { initializeApp, getApps, type FirebaseApp } from 'firebase/app';
import { getMessaging, getToken, isSupported, onMessage, type Messaging } from 'firebase/messaging';
import { apiFetch } from '@/lib/api';
import type { FirebasePublicConfig } from '@/lib/firebase-config';

const SW_PATH = '/firebase-messaging-sw.js';
const REGISTERED_TOKEN_KEY = 'lendry_fcm_token';

let messagingInstance: Messaging | null = null;

function getFirebaseApp(config: FirebasePublicConfig): FirebaseApp {
  const existing = getApps()[0];
  if (existing) return existing;

  return initializeApp({
    apiKey: config.apiKey,
    authDomain: `${config.projectId}.firebaseapp.com`,
    projectId: config.projectId,
    messagingSenderId: config.messagingSenderId,
    appId: config.appId
  });
}

async function ensureServiceWorker() {
  if (!('serviceWorker' in navigator)) return null;
  const registration = await navigator.serviceWorker.register(SW_PATH, { scope: '/' });
  await navigator.serviceWorker.ready;
  return registration;
}

export async function registerFirebasePush(authToken: string, config: FirebasePublicConfig) {
  if (typeof window === 'undefined') return null;
  if (!config.enabled) return null;

  const supported = await isSupported();
  if (!supported) return null;

  if (!('Notification' in window)) return null;

  const permission = Notification.permission === 'granted'
    ? 'granted'
    : await Notification.requestPermission();

  if (permission !== 'granted') return null;

  const registration = await ensureServiceWorker();
  if (!registration) return null;

  const app = getFirebaseApp(config);
  messagingInstance = getMessaging(app);

  const fcmToken = await getToken(messagingInstance, {
    vapidKey: config.vapidKey,
    serviceWorkerRegistration: registration
  });

  if (!fcmToken) return null;

  const previousToken = window.localStorage.getItem(REGISTERED_TOKEN_KEY);
  if (previousToken && previousToken !== fcmToken) {
    try {
      await apiFetch('/notifications/push/register', {
        method: 'DELETE',
        body: JSON.stringify({ token: previousToken })
      }, authToken);
    } catch {
      // ignore stale unregister errors
    }
  }

  await apiFetch('/notifications/push/register', {
    method: 'POST',
    body: JSON.stringify({
      token: fcmToken,
      platform: 'WEB',
      deviceLabel: navigator.userAgent.slice(0, 120)
    })
  }, authToken);

  window.localStorage.setItem(REGISTERED_TOKEN_KEY, fcmToken);
  return fcmToken;
}

export function subscribeFirebaseForegroundMessages(listener: (payload: { title: string; message: string; data?: Record<string, string> }) => void) {
  if (!messagingInstance) return () => undefined;

  return onMessage(messagingInstance, (payload) => {
    listener({
      title: payload.notification?.title ?? payload.data?.title ?? 'Уведомление',
      message: payload.notification?.body ?? payload.data?.message ?? '',
      data: payload.data
    });
  });
}

export async function unregisterFirebasePush(authToken: string | null) {
  const stored = typeof window !== 'undefined' ? window.localStorage.getItem(REGISTERED_TOKEN_KEY) : null;
  if (!stored || !authToken) return;

  try {
    await apiFetch('/notifications/push/register', {
      method: 'DELETE',
      body: JSON.stringify({ token: stored })
    }, authToken);
  } catch {
    // ignore logout cleanup errors
  } finally {
    window.localStorage.removeItem(REGISTERED_TOKEN_KEY);
  }
}
