import { readonly, ref } from 'vue'

const toasts = ref([])
let toastSeq = 0
const TOAST_EXIT_MS = 220

function clearToastTimer(toast) {
  if (toast?.timerId) {
    window.clearTimeout(toast.timerId)
    toast.timerId = 0
  }
}

function removeToast(id) {
  toasts.value = toasts.value.filter((toast) => toast.id !== id)
}

function dismissToast(id) {
  const target = toasts.value.find((toast) => toast.id === id)
  if (!target || target.isClosing) return

  clearToastTimer(target)
  target.isClosing = true
  target.timerId = window.setTimeout(() => removeToast(id), TOAST_EXIT_MS)
}

function showToast(message, { type = 'info', duration = 2600 } = {}) {
  if (!message) return ''
  const duplicated = toasts.value.find((toast) => toast.message === message && toast.type === type && !toast.isClosing)

  if (duplicated) {
    duplicated.count = (duplicated.count || 1) + 1
    clearToastTimer(duplicated)
    if (duration > 0) {
      duplicated.timerId = window.setTimeout(() => dismissToast(duplicated.id), duration)
    }
    toasts.value = [...toasts.value]
    return duplicated.id
  }

  const id = `toast-${++toastSeq}`
  const nextToast = { id, message, type, count: 1, isClosing: false, timerId: 0 }
  toasts.value = [...toasts.value, nextToast]

  if (duration > 0) {
    nextToast.timerId = window.setTimeout(() => dismissToast(id), duration)
  }

  return id
}

export function useToast() {
  return {
    toasts: readonly(toasts),
    dismissToast,
    showToast,
    success: (message, options = {}) => showToast(message, { type: 'success', ...options }),
    error: (message, options = {}) => showToast(message, { type: 'error', ...options }),
    info: (message, options = {}) => showToast(message, { type: 'info', ...options }),
  }
}
