import {create} from 'zustand';
import {useShallow} from 'zustand/react/shallow';

import {InAppNotificationBody} from './interfaces';

export const IN_APP_NOTIFICATION_MAX_QUEUE_SIZE = 10;

interface InAppNotificationStore {
  queue: InAppNotificationBody[];
  push: (notification: InAppNotificationBody) => void;
  updateItem: (notification: InAppNotificationBody) => void;
  shift: () => void;
  clear: () => void;
}

const store = create<InAppNotificationStore>(set => ({
  queue: [],
  push: notification => {
    set(state => {
      const newQueue = [...state.queue, notification];

      // If queue exceeds max size, keep the first (potentially visible) notification
      // and the most recent ones, dropping older ones in between
      if (newQueue.length > IN_APP_NOTIFICATION_MAX_QUEUE_SIZE) {
        const firstNotification = newQueue[0]; // Keep the first (potentially visible)
        const recentNotifications = newQueue.slice(
          -(IN_APP_NOTIFICATION_MAX_QUEUE_SIZE - 1),
        ); // Keep most recent

        return {
          queue: [firstNotification, ...recentNotifications],
        };
      }

      return {
        queue: newQueue,
      };
    });
  },
  updateItem: notification => {
    set(state => ({
      queue: state.queue.map(item =>
        item.collapsedId === notification.collapsedId
          ? {...notification, id: item.id, updatedAt: notification.updatedAt}
          : item,
      ),
    }));
  },
  shift: () => {
    set(state => ({
      queue: state.queue.slice(1),
    }));
  },
  clear: () => set({queue: []}),
}));

export const useFirstNotification = () =>
  store(useShallow(state => state.queue[0]));

export const pushNotification = (notification: InAppNotificationBody) => {
  store.getState().push(notification);
};

export const updateNotification = (notification: InAppNotificationBody) => {
  store.getState().updateItem(notification);
};

export const shiftNotification = () => {
  store.getState().shift();
};

export const clearNotifications = () => {
  store.getState().clear();
};

export const getVisibleNotification = () => {
  const queue = store.getState().queue;
  return queue.at(0);
};
