'use client';

import { createContext, useContext, useState, useEffect, useCallback, ReactNode } from 'react';
import { useEffectiveDriverId } from '@/lib/currentDriver';

import type { Notification } from '@core/notifications/application';
import ToastNotification from './ToastNotification';
import ModalNotification from './ModalNotification';

interface NotificationContextValue {
  notifications: Notification[];
  unreadCount: number;
  toastNotifications: Notification[];
  modalNotification: Notification | null;
  markAsRead: (notification: Notification) => Promise<void>;
  dismissToast: (notification: Notification) => void;
  respondToModal: (notification: Notification, actionId?: string) => Promise<void>;
  dismissModal: (notification: Notification) => Promise<void>;
}

const NotificationContext = createContext<NotificationContextValue | null>(null);

export function useNotifications() {
  const context = useContext(NotificationContext);
  if (!context) {
    throw new Error('useNotifications must be used within NotificationProvider');
  }
  return context;
}

interface NotificationProviderProps {
  children: ReactNode;
}

export default function NotificationProvider({ children }: NotificationProviderProps) {
  const [notifications, setNotifications] = useState<Notification[]>([]);
  const [toastNotifications, setToastNotifications] = useState<Notification[]>([]);
  const [modalNotification, setModalNotification] = useState<Notification | null>(null);
  const [seenNotificationIds, setSeenNotificationIds] = useState<Set<string>>(new Set());
  
  const currentDriverId = useEffectiveDriverId();

  // Poll for new notifications
  // TODO
  // useEffect(() => {
  //   const loadNotifications = async () => {
  //     try {
  //       const repo = getNotificationRepository();
  //       const allNotifications = await repo.findByRecipientId(currentDriverId);
  //       setNotifications(allNotifications);

  //       // Check for new notifications that need toast/modal display
  //       allNotifications.forEach((notification) => {
  //         // Check both unread and action_required status for modals
  //         const shouldDisplay = (notification.isUnread() || notification.isActionRequired()) &&
  //                              !seenNotificationIds.has(notification.id);
          
  //         if (shouldDisplay) {
  //           // Mark as seen to prevent duplicate displays
  //           setSeenNotificationIds((prev) => new Set([...prev, notification.id]));

  //           // Handle based on urgency
  //           if (notification.isModal()) {
  //             // Modal takes priority - show immediately
  //             setModalNotification(notification);
  //           } else if (notification.isToast()) {
  //             // Add to toast queue
  //             setToastNotifications((prev) => [...prev, notification]);
  //           }
  //           // Silent notifications just appear in the notification center
  //         }
  //       });
  //     } catch (error) {
  //       console.error('Failed to load notifications:', error);
  //     }
  //   };

  //   loadNotifications();
    
  //   // Poll every 2 seconds for responsiveness
  //   const interval = setInterval(loadNotifications, 2000);
  //   return () => clearInterval(interval);
  // }, [currentDriverId, seenNotificationIds]);

  // Prevent body scroll when modal is open
  useEffect(() => {
    if (modalNotification) {
      document.body.style.overflow = 'hidden';
      return () => {
        document.body.style.overflow = '';
      };
    }
  }, [modalNotification]);

  const markAsRead = useCallback(async (notification: Notification) => {
    try {
      const markRead = getMarkNotificationReadUseCase();
      await markRead.execute({
        notificationId: notification.id,
        recipientId: currentDriverId,
      });

      setNotifications((prev) =>
        prev.map((n) => (n.id === notification.id ? n.markAsRead() : n))
      );
    } catch (error) {
      console.error('Failed to mark notification as read:', error);
    }
  }, [currentDriverId]);

  const dismissToast = useCallback((notification: Notification) => {
    setToastNotifications((prev) => prev.filter((n) => n.id !== notification.id));
  }, []);

  const respondToModal = useCallback(async (notification: Notification, actionId?: string) => {
    try {
      // Mark as responded
      const repo = getNotificationRepository();
      const updated = notification.markAsResponded(actionId);
      await repo.update(updated);

      // Update local state
      setNotifications((prev) =>
        prev.map((n) => (n.id === notification.id ? updated : n))
      );

      // Clear modal
      setModalNotification(null);
    } catch (error) {
      console.error('Failed to respond to notification:', error);
    }
  }, []);

  const dismissModal = useCallback(async (notification: Notification) => {
    try {
      // Dismiss the notification
      const repo = getNotificationRepository();
      const updated = notification.dismiss();
      await repo.update(updated);

      // Update local state
      setNotifications((prev) =>
        prev.map((n) => (n.id === notification.id ? updated : n))
      );

      // Clear modal
      setModalNotification(null);
    } catch (error) {
      console.error('Failed to dismiss notification:', error);
    }
  }, []);

  const unreadCount = notifications.filter((n) => n.isUnread() || n.isActionRequired()).length;

  const value: NotificationContextValue = {
    notifications,
    unreadCount,
    toastNotifications,
    modalNotification,
    markAsRead,
    dismissToast,
    respondToModal,
    dismissModal,
  };

  return (
    <NotificationContext.Provider value={value}>
      {children}

      {/* Toast notifications container */}
      <div className="fixed top-20 right-4 z-50 space-y-3">
        {toastNotifications.map((notification) => (
          <ToastNotification
            key={notification.id}
            notification={notification}
            onDismiss={dismissToast}
            onRead={markAsRead}
          />
        ))}
      </div>

      {/* Modal notification */}
      {modalNotification && (
        <ModalNotification
          notification={modalNotification}
          onAction={respondToModal}
          onDismiss={dismissModal}
        />
      )}
    </NotificationContext.Provider>
  );
}