'use client';
// components/FcmInit.tsx
//
// Mounts inside DashboardLayout (authenticated area, behind AuthGuard).
// Registers the FCM service worker, requests notification permission, obtains
// the device token, and wires foreground messages to sonner toasts.
//
// Renders nothing — purely a side-effect component.

import { useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { toast } from 'sonner';
import {
  getCurrentFcmToken,
  getMessagingServiceWorkerRegistration,
  hasPendingFcmTokenSync,
  isPushEnvironmentAvailable,
  onForegroundMessage,
} from '@/lib/firebase/messaging';
import type { MessagePayload } from 'firebase/messaging';
import { refreshUnreadNotificationCount } from '@/lib/notifications/count';
import { isIgnoredNotificationType, routeForNotificationType } from '@/lib/notifications/routes';

function routeForType(
  type: string,
  data?: Record<string, string | undefined>,
): string | null {
  return routeForNotificationType(type, data);
}

// ---------------------------------------------------------------------------
// Toast variant selector
// ---------------------------------------------------------------------------
type ToastVariant = 'default' | 'success' | 'error' | 'warning' | 'info';

function variantForType(type: string): ToastVariant {
  switch (type) {
    case 'settlement_accepted':
    case 'settlement_transferred':
    case 'settlement_invoice_ready':
    case 'settlement_objection_resolved':
    case 'entity_approved':
    case 'entity_update_approved':
    case 'scooters_assigned':
      return 'success';
    case 'settlement_rejected':
    case 'entity_update_rejected':
      return 'warning';
    case 'entity_rejected':
    case 'blocked':
      return 'error';
    case 'entity_needs_approval':
    case 'admin_notify':
      return 'info';
    default:
      if (type.includes('approved') && type.includes('profile')) {
        return 'success';
      }
      if (type.includes('rejected') && type.includes('profile')) {
        return 'error';
      }
      return 'default';
  }
}

// ---------------------------------------------------------------------------
// showFcmToast — converts an FCM payload into a sonner toast
// ---------------------------------------------------------------------------
function notifyUnreadCountChanged(): void {
  void refreshUnreadNotificationCount();
}

function showFcmToast(
  payload: MessagePayload,
  push: (route: string) => void,
): void {
  const type = payload.data?.type ?? '';

  if (type && isIgnoredNotificationType(type)) {
    return;
  }

  const route = type ? routeForType(type, payload.data) : null;

  const title =
    payload.notification?.title ??
    payload.data?.title ??
    'إشعار جديد';

  const body =
    payload.notification?.body ??
    payload.data?.body ??
    '';

  const variant = type ? variantForType(type) : 'default';

  const toastOptions = {
    description: body || undefined,
    duration: route ? 8000 : 6000,
    ...(route
      ? {
          action: {
            label: 'عرض',
            onClick: () => push(route),
          },
        }
      : {}),
  };

  switch (variant) {
    case 'success':
      toast.success(title, toastOptions);
      break;
    case 'error':
      toast.error(title, toastOptions);
      break;
    case 'warning':
      toast.warning(title, toastOptions);
      break;
    case 'info':
      toast.info(title, toastOptions);
      break;
    default:
      toast(title, toastOptions);
  }

  notifyUnreadCountChanged();
}

function handleForegroundMessage(
  payload: MessagePayload,
  push: (route: string) => void,
): void {
  showFcmToast(payload, push);
}

async function initializeFcm(
  push: (route: string) => void,
): Promise<(() => void) | null> {
  if (!isPushEnvironmentAvailable()) {
    return null;
  }

  const swReg = await getMessagingServiceWorkerRegistration();
  if (!swReg) {
    return null;
  }

  const token = await getCurrentFcmToken({ requestPermission: true, swReg });
  if (token && hasPendingFcmTokenSync(token)) {
    // BACKEND TOKEN-SYNC CONTRACT REQUIRED — no post-auth device_id endpoint exists.
    // Auth flows (/provider/login, /provider/verify-login) send device_id at sign-in.
    // Example when available: apiFetch('/provider/fcm-token', { method: 'POST', body: { fcm_token: token } })
  }

  return onForegroundMessage((payload) => {
    handleForegroundMessage(payload, push);
  });
}

// ---------------------------------------------------------------------------
// Component
// ---------------------------------------------------------------------------
export default function FcmInit() {
  const router = useRouter();

  useEffect(() => {
    let unsubForeground: (() => void) | null = null;

    initializeFcm((route) => {
      router.push(route);
    }).then((unsub) => {
      unsubForeground = unsub;
    });

    return () => {
      unsubForeground?.();
    };
  }, [router]);

  return null;
}
