<script lang="ts" setup>
import type { Message, MessageType } from '../../types/Message';

const props = defineProps({
  max: {
    type: Number,
    default: 5,
  },
})

const nuxtApp = useNuxtApp()
const messageList = ref<Message[]>([])

const createMessage = (content: string, type: MessageType, duration: number = 3000) => {
  const { max } = props
  messageList.value.push({
    id: (Date.now() + Math.random() * 100).toString(32).toUpperCase(),
    content,
    type,
    duration,
  })
  if (messageList.value.length > max) {
    messageList.value.shift()
  }
}

const providerApi = {
  destroy: (id: string) => {
    if (!messageList.value.find(message => message.id === id)) return
    messageList.value.splice(messageList.value.findIndex(message => message.id === id), 1)
  },
}

const api = {
  info: (content: string, duration: number = 3000) => {
    createMessage(content, 'info', duration)
  },
  success: (content: string, duration: number = 3000) => {
    createMessage(content, 'success', duration)
  },
  warning: (content: string, duration: number = 3000) => {
    createMessage(content, 'warning', duration)
  },
  error: (content: string, duration: number = 3000) => {
    createMessage(content, 'error', duration)
  },
}

nuxtApp.vueApp.provide('ray-message-provider', providerApi)
nuxtApp.vueApp.provide('ray-message', api)
</script>

<template>
  <slot></slot>
  <teleport to="body">
    <div id="message-provider">
      <div class="message-wrapper">
        <TransitionGroup name="message">
          <RayMessage v-for="(message, k) in messageList" :key="message.id" :message="message" />
        </TransitionGroup>
      </div>
    </div>
  </teleport>
</template>

<style scoped>
#message-provider .message-wrapper {
  @apply z-[50000] fixed inset-0 flex flex-col items-center pointer-events-none;
}

.message-move,
.message-leave-active {
  transition: all .8s cubic-bezier(0.075, 0.82, 0.165, 1);
}

.message-enter-active {
  transition: all .8s cubic-bezier(0.075, 0.82, 0.165, 1);
}

.message-enter-from {
  filter: blur(2px);
  opacity: 0;
  transform: translateY(-100%);
}

.message-leave-to {
  filter: blur(6px);
  opacity: 0;
  transform: translateY(-20%);
}

.message-leave-active {
  position: absolute;
}
</style>
