import { computed, ref, watch, type Ref } from 'vue'

export type AdminToastTone = 'success' | 'error' | 'info'

export interface AdminToast {
  id: number
  message: string
  tone: AdminToastTone
}

const activeToast = ref<AdminToast | null>(null)
let toastId = 0
let hideTimer: number | undefined

export function useAdminToast() {
  function dismissAdminToast(id?: number) {
    if (id && activeToast.value?.id !== id) return
    activeToast.value = null

    if (hideTimer !== undefined && typeof window !== 'undefined') {
      window.clearTimeout(hideTimer)
      hideTimer = undefined
    }
  }

  function showAdminToast(message: string, tone: AdminToastTone = 'info', durationMs = tone === 'error' ? 6200 : 4200) {
    const trimmedMessage = message.trim()
    if (!trimmedMessage) return

    if (hideTimer !== undefined && typeof window !== 'undefined') {
      window.clearTimeout(hideTimer)
      hideTimer = undefined
    }

    const id = ++toastId
    activeToast.value = { id, message: trimmedMessage, tone }

    if (typeof window !== 'undefined') {
      hideTimer = window.setTimeout(() => dismissAdminToast(id), durationMs)
    }
  }

  return {
    toast: computed(() => activeToast.value),
    showAdminToast,
    dismissAdminToast,
  }
}

export function watchAdminToast(adminMessage: Ref<string>, adminError: Ref<string>) {
  const { showAdminToast } = useAdminToast()

  watch(
    adminMessage,
    (message) => {
      if (message.trim()) {
        showAdminToast(message, 'success')
      }
    },
    { flush: 'post' },
  )

  watch(
    adminError,
    (error) => {
      if (error.trim()) {
        showAdminToast(error, 'error')
      }
    },
    { flush: 'post' },
  )
}

export function watchAdminErrorToast(adminError: Ref<string>) {
  const { showAdminToast } = useAdminToast()

  watch(
    adminError,
    (error) => {
      if (error.trim()) {
        showAdminToast(error, 'error')
      }
    },
    { flush: 'post' },
  )
}
