/**
 * useNotifications Hook - Platform-aware notifications management
 * Uses Firebase abstraction layer for cross-platform support
 */
import { useState, useEffect, useCallback } from 'react';
import { collection } from '../firebase';
import { NotificationService } from '../services/notificationService';
import { useGlobalLoading } from './useGlobalLoading';

export interface UseNotificationsReturn {
  notifications: any[];
  loading: boolean;
  error: string | null;
  unreadCount: number;
  markAsRead: (notificationId: string) => Promise<void>;
  markAllAsRead: () => Promise<void>;
  refreshNotifications: () => void;
}

export function useNotifications(uid: string | null): UseNotificationsReturn {
  const [notifications, setNotifications] = useState<any[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const { withLoading } = useGlobalLoading();

  // Calculate unread count
  const unreadCount = notifications.filter(notification => !notification.read).length;

  // Mark single notification as read
  const markAsRead = async (notificationId: string): Promise<void> => {
    try {
      const result = await withLoading(() => NotificationService.markAsRead(notificationId));
      if (result.success) {
        // Update local state
        setNotifications(prev =>
          prev.map(notification =>
            notification.id === notificationId
              ? { ...notification, read: true, updatedAt: new Date() }
              : notification
          )
        );
      } else {
        setError(result.error || 'Failed to mark notification as read');
      }
    } catch (err) {
      console.error('Error marking notification as read:', err);
      setError('Failed to mark notification as read');
    }
  };

  // Mark all notifications as read
  const markAllAsRead = async (): Promise<void> => {
    try {
      // Update all notifications in local state
      setNotifications(prev =>
        prev.map(notification => ({ ...notification, read: true, updatedAt: new Date() }))
      );

      // Update in Firestore
      const unreadNotifications = notifications.filter(n => !n.read);
      const updatePromises = unreadNotifications.map(notification =>
        notification.id ? withLoading(() => NotificationService.markAsRead(notification.id)) : Promise.resolve({ success: true })
      );

      await Promise.all(updatePromises);
    } catch (err) {
      console.error('Error marking all notifications as read:', err);
      setError('Failed to mark all notifications as read');
    }
  };

  // Refresh notifications
  const [refreshKey, setRefreshKey] = useState(0);

  const refreshNotifications = useCallback((): void => {
    setLoading(true);
    setError(null);
  }, []);

  useEffect(() => {
    let isMounted = true;

    const fetchNotifications = async () => {
      if (!uid) {
        if (isMounted) {
          setNotifications([]);
          setLoading(false);
          setError(null);
        }
        return;
      }

      if (isMounted) {
        setLoading(true);
        setError(null);
      }

      try {
        const notificationsCollection = collection('notifications');
        const snapshot = await withLoading(async () => {
          return await notificationsCollection
            .where('userId', '==', uid)
            .orderBy('createdAt', 'desc')
            .get();
        }) as any;

        const notificationsData: any[] = [];

        if (snapshot && snapshot.forEach) {
          snapshot.forEach((docData: any) => {
            const data = docData.data();
            notificationsData.push({
              id: docData.id,
              ...data,
            });
          });
        }

        if (isMounted) {
          setNotifications(notificationsData);
          setLoading(false);
          setError(null);
        }
      } catch (err) {
        console.error('Error fetching notifications:', err);
        if (isMounted) {
          setError('Failed to fetch notifications');
          setLoading(false);
        }
      }
    };

    void fetchNotifications();

    return () => {
      isMounted = false;
    };
  }, [uid, refreshKey, withLoading]);

  return {
    notifications,
    loading,
    error,
    unreadCount,
    markAsRead,
    markAllAsRead,
    refreshNotifications,
  };
}
