import type { ExternalToast } from "vue-sonner"
import { toast } from "vue-sonner"

export { default as Toaster } from "./Toaster.vue"
export { toast } from "vue-sonner"
export type { ExternalToast, ToasterProps } from "vue-sonner"

/**
 * Default toast options shared across the modui. Consumers can pass
 * additional fields via the `options` argument to override these.
 */
export const TOAST_DEFAULTS = {
  duration: 4000,
} satisfies ExternalToast

export interface UseToastApi {
  toast: typeof toast
  success: (message: string, options?: ExternalToast) => string | number
  error: (message: string, options?: ExternalToast) => string | number
  warning: (message: string, options?: ExternalToast) => string | number
  info: (message: string, options?: ExternalToast) => string | number
  loading: (message: string, options?: ExternalToast) => string | number
  message: (message: string, options?: ExternalToast) => string | number
  dismiss: (id?: string | number) => string | number | void
}

/**
 * Thin wrapper around `vue-sonner`'s `toast()` that applies the
 * library's default options. Returns helpers for each toast type plus
 * a `dismiss` shortcut.
 */
export function useToast(): UseToastApi {
  function merge(options?: ExternalToast): ExternalToast {
    return { ...TOAST_DEFAULTS, ...(options ?? {}) }
  }

  return {
    toast,
    success: (m, o) => toast.success(m, merge(o)),
    error: (m, o) => toast.error(m, merge(o)),
    warning: (m, o) => toast.warning(m, merge(o)),
    info: (m, o) => toast.info(m, merge(o)),
    loading: (m, o) => toast.loading(m, merge(o)),
    message: (m, o) => toast.message(m, merge(o)),
    dismiss: id => toast.dismiss(id),
  }
}
