import { v4 as uuid } from 'uuid';
import type { App, InjectionKey, Ref } from 'vue';
import { inject, ref } from 'vue';
import {
  Notification,
  NotificationInstance,
  NotificationSettings,
  NotificationType,
} from './notification.model';
import NotificationWidget from './NotificationWidget.vue';
import { Problem } from '@/models';

export const BmsNotificationsInstance =
  Symbol() as InjectionKey<NotificationInstance>;

export const notifications = {
  install(app: App, pluginSettings?: NotificationSettings) {
    const notifications = ref<Notification[]>([]);
    const settings: NotificationSettings = Object.assign(
      {},
      {
        display: 10,
        delay: 4000,
      },
      pluginSettings,
    );

    app.provide<Ref<Notification[]>>('notifications', notifications);

    const notify = (
      type: NotificationType,
      text: string,
      time: number,
      details?: string | Problem,
    ) => {
      const newNotification = { type, text, details, id: uuid() };

      notifications.value.push(newNotification);
      notifications.value = notifications.value.slice(-settings.display);

      if (time > 0) {
        setTimeout(() => {
          notifications.value = notifications.value.filter(
            (notification) => notification.id !== newNotification.id,
          );
        }, time);
      }
    };

    const dismiss = (id: string) => {
      notifications.value = notifications.value.filter(
        (notification) => notification.id !== id,
      );
    };

    app.provide<NotificationInstance>(BmsNotificationsInstance, {
      success: (text: string, details: string = '', time = settings.delay) => {
        notify(NotificationType.success, text, time, details);
      },
      error: (text: string, details: string | Problem = '', time = 0) => {
        notify(NotificationType.error, text, time, details);
      },
      dismiss: (id: string) => {
        dismiss(id);
      },
    });

    app.component('bms-notifications', NotificationWidget);
    app.component('BmsNotifications', NotificationWidget);
  },
};

export function useNotifications() {
  const notify = inject(BmsNotificationsInstance, {
    success: () => {},
    error: () => {},
    dismiss: () => {},
  });

  return {
    success: notify.success,
    error: notify.error,
  };
}
