import useSWR, { mutate } from 'swr';
import { getNotificationsByEmail } from '@/shared/api/notif';

const NOTIFICATIONS_KEY = '/api/notifications';
const STORAGE_KEY = 'readNotifications';

interface INotification {
  dateTime: string;
  title: string;
  message: string;
  type: string | null;
}

interface INotificationWithRead extends INotification {
  isRead: boolean;
}

export function useNotifications() {
  const getReadNotifications = (): string[] => {
    try {
      const stored = localStorage.getItem(STORAGE_KEY);
      return stored ? JSON.parse(stored) : [];
    } catch (error) {
      console.error('Error reading from localStorage:', error);
      return [];
    }
  };

  const saveReadNotifications = (readIds: string[]) => {
    try {
      localStorage.setItem(STORAGE_KEY, JSON.stringify(readIds));
    } catch (error) {
      console.error('Error saving to localStorage:', error);
    }
  };

  const { data: rawNotifications = [], isLoading, mutate: mutateNotifications } = useSWR(
    NOTIFICATIONS_KEY,
    async () => {
      const data = await getNotificationsByEmail();  
      const readIds = getReadNotifications();
      return data.map((notification: INotification) => ({
        ...notification,
        isRead: readIds.includes(notification.dateTime),
      }));
    },
    {
      refreshInterval: 5000,
      revalidateOnFocus: true,
      revalidateOnReconnect: true,
      refreshWhenHidden: true,
      refreshWhenOffline: false,
    }
  );

  const markAsRead = (notification: INotificationWithRead) => {
    const readIds = getReadNotifications();
    if (!readIds.includes(notification.dateTime)) {
      const newReadIds = [...readIds, notification.dateTime];
      saveReadNotifications(newReadIds);

      mutateNotifications(
        (rawNotifications || []).map((n: INotificationWithRead) =>
          n.dateTime === notification.dateTime
            ? { ...n, isRead: true }
            : n
        ),
        false
      );
    }
  };

  const markAllAsRead = () => {
    const allIds = (rawNotifications || []).map((n: INotificationWithRead) => n.dateTime);
    saveReadNotifications(allIds);

    mutateNotifications(
      (rawNotifications || []).map((n: INotificationWithRead) => ({ ...n, isRead: true })),
      false
    );
  };

  const refresh = async () => {
    await mutateNotifications();
  };

  const unreadCount = (rawNotifications || []).filter(
    (n: INotificationWithRead) => !n.isRead
  ).length;

  const addNotification = async (newNotification: INotification) => {
    await mutateNotifications(async (currentData: INotificationWithRead[]) => {
      const readIds = getReadNotifications();
      const notificationWithRead = {
        ...newNotification,
        isRead: false,
      };
      return [notificationWithRead, ...(currentData || [])];
    }, false);
  };

  return {
    notifications: rawNotifications as INotificationWithRead[],
    isLoading,
    markAsRead,
    markAllAsRead,
    refresh,
    unreadCount,
    addNotification,
  };
}

export const refreshNotifications = () => {
  mutate(NOTIFICATIONS_KEY);
};

export const addGlobalNotification = async (notification: INotification) => {
  await mutate(
    NOTIFICATIONS_KEY,
    async (currentData: INotificationWithRead[] = []) => {
      const notificationWithRead = {
        ...notification,
        isRead: false,
      };
      return [notificationWithRead, ...currentData];
    },
    false
  );
};