<template>
  <Teleport to="body">
    <div class="bms-notifications">
      <div class="bms-notifications__list">
        <TransitionGroup name="bms-notifactions-transition">
          <NotificationItem
            v-for="notification in notifications"
            :key="notification.id"
            :notification="notification"
            class="bms-notifications__item"
            @close="close(notification)"
            @open-details="openDetails(notification)"
          />
        </TransitionGroup>
      </div>
    </div>
  </Teleport>
  <BmsModal
    :model-value="openNotification"
    :type="
      openNotification?.type === NotificationType.error
        ? StatusType.Danger
        : StatusType.Default
    "
    title="Détails"
    :buttons="modalButtons"
    @submit="closeDetails"
    @close="closeDetails"
    priority
  >
    <template #default>
      <BmsProblem
        v-if="isProblem(openNotification?.details)"
        :problem="openNotification?.details as Problem"
      />
      <template v-else>{{ openNotification?.details }}</template>
    </template>
  </BmsModal>
</template>

<script setup lang="ts">
import { Ref, inject, ref } from 'vue';
import { BmsNotificationsInstance } from './index';
import { Notification, NotificationType } from './notification.model';
import NotificationItem from './NotificationItem.vue';
import {
  BmsModal,
  BmsProblem,
  ModalActionButton,
  StatusType,
  type Problem,
  isProblem,
} from '@/index';

const notifications: Notification[] | undefined = inject('notifications');
const notify: any = inject(BmsNotificationsInstance);
const openNotification: Ref<Notification | null> = ref(null);

const modalButtons: ModalActionButton[] = [
  {
    label: 'Fermer',
    role: 'submit',
    action: () => {
      closeDetails();
      return Promise.resolve(false);
    },
  },
];

const close = (notification: Notification) => {
  notify.dismiss(notification.id);
};

const openDetails = (notification: Notification) => {
  close(notification);
  openNotification.value = notification;
};

const closeDetails = () => {
  openNotification.value = null;
};
</script>

<style lang="scss" scoped>
.bms-notifications {
  --bms-notifications-width: 360px;
  --bms-notifications-margin: 1em 0 0;
  --bms-notifications-left: initial;
  --bms-notifications-right: 1em;
  --bms-notifications-bottom: 1em;
  --bms-notifications-top: initial;
  --bms-notifications-transition-duration: 0.4s;
  --bms-notifications-transition-timing-function: ease-in-out;
  --bms-notifications-enter-translate: 2em;

  position: fixed;
  left: var(--bms-notifications-left);
  right: var(--bms-notifications-right);
  bottom: var(--bms-notifications-bottom);
  top: var(--bms-notifications-top);
  width: 100%;
  max-width: var(--bms-notifications-width);
  z-index: var(--bms-z-index-fixed);

  &__item {
    &:not(:first-child) {
      margin: var(--bms-notifications-margin);
    }
  }
}

.bms-notifactions-transition-move,
.bms-notifactions-transition-enter-active,
.bms-notifactions-transition-leave-active {
  transition: all var(--bms-notifications-transition-duration)
    var(--bms-notifications-transition-timing-function);
}
.bms-notifactions-transition-enter-from,
.bms-notifactions-transition-leave-to {
  opacity: 0;
}
.bms-notifactions-transition-enter-from {
  transform: translateX(var(--bms-notifications-enter-translate));
}

.bms-notifactions-transition-leave-active {
  position: absolute;
}
</style>
