<template>
  <div>
    <v-snackbar
      v-for="(snackbar, index) in snackbars"
      :key="index"
      v-model="snackbar.show"
      :color="snackbar.color || 'blue'"
      :timeout="snackbar.timeout ?? -1"
      :style="{ 'margin-bottom': calcMargin(index) }"
      @click="handleSnackbarClick(index)"
    >
      <template v-if="snackbar.content && snackbar.i18n">
        {{ $t(snackbar.i18n, snackbar.content) }}
      </template>
      <template v-else-if="snackbar.i18n">
        {{ $t(snackbar.i18n) }}
      </template>
      <template v-else>
        {{ snackbar.message }}
      </template>

      <template #actions>
        <v-btn
          v-if="snackbar.timeout < 0"
          icon="mdi-close"
          variant="text"
          @click="handleSnackbarClick(index)"
        />
      </template>
    </v-snackbar>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue"
import { $store, $eventbus } from "@racletteCore/main"

export type SnackbarMessage = {
  message?: string
  content?: Record<string, any>
  i18n?: string
  color?: string
  timeout?: number
  sender?: string
}
export type ScopedSnackbarMessage = {
  sender: string
  data: {
    message?: string
    content?: Record<string, any>
    i18n?: string
    color?: string
    timeout?: number
  }
}
const snackbars = ref<(SnackbarMessage & { show: boolean })[]>([])

const defaultTimeout = 4000

// Function to calculate margin for stacking snackbars
const calcMargin = (index: number) => `${index * 60 + 10}px`

// Function to close the snackbar
// the close icon will only be shown if the bar has no timeout
const handleSnackbarClick = (index: number) => snackbars.value.splice(index, 1)

const addToSnackBar = (data: SnackbarMessage | ScopedSnackbarMessage) => {
  // TODO implement proper handling of sender attribute
  const _data = data?.sender ? data.data : data
  const snackbar = { ..._data, show: true }

  // Prevent duplicate messages (check last two)
  const lastMessages = snackbars.value.slice(-2)
  const isDuplicate = lastMessages.some(
    (lastMsg) => !$store.hasChanges(lastMsg, snackbar),
  )

  if (isDuplicate) {
    return
  }

  snackbars.value.push(snackbar)

  if (snackbar.timeout !== -1) {
    setTimeout(() => {
      const index = snackbars.value.indexOf(snackbar)

      if (index !== -1) {
        snackbars.value.splice(index, 1)
      }
    }, snackbar.timeout ?? defaultTimeout)
  }
}

onMounted(() => $eventbus.on("ui/addToSnackbar", addToSnackBar))

onUnmounted(() => $eventbus.removeListener("ui/addToSnackbar", addToSnackBar))
</script>
