import { useEffect } from 'react'
import { create } from 'zustand'
import { cn } from '@/lib/cn'

type ToastTone = 'info' | 'error'
interface Toast {
  id: number
  message: string
  tone: ToastTone
}

interface ToastState {
  toasts: Toast[]
  push: (message: string, tone?: ToastTone) => void
  dismiss: (id: number) => void
}

let nextId = 1

export const useToastStore = create<ToastState>((set) => ({
  toasts: [],
  push: (message, tone = 'info') => set((s) => ({ toasts: [...s.toasts, { id: nextId++, message, tone }] })),
  dismiss: (id) => set((s) => ({ toasts: s.toasts.filter((t) => t.id !== id) })),
}))

/** Fire a toast from anywhere (including non-component code). */
export const toast = {
  info: (m: string) => useToastStore.getState().push(m, 'info'),
  error: (m: string) => useToastStore.getState().push(m, 'error'),
}

// Param is `item`, not `toast`, so it doesn't shadow the module's `toast` export.
function ToastItem({ item }: { item: Toast }) {
  const dismiss = useToastStore((s) => s.dismiss)
  const isError = item.tone === 'error'
  useEffect(() => {
    // Error toasts are the primary report that a mutation failed, so they do NOT
    // auto-dismiss — a user who looked away at second 4 would otherwise lose the
    // only notice, with nothing to retrieve (#85). Info toasts still time out.
    if (isError) return
    const t = setTimeout(() => dismiss(item.id), 4000)
    return () => clearTimeout(t)
  }, [item.id, dismiss, isError])
  return (
    <div
      role={isError ? 'alert' : 'status'}
      className={cn(
        'pointer-events-auto flex items-start gap-2 rounded-md border px-3 py-2 text-sm shadow-md',
        isError
          ? 'border-red-500/40 bg-red-500/10 text-red-700 dark:text-red-300'
          : 'border-border bg-surface text-fg',
      )}
    >
      <span className="flex-1">{item.message}</span>
      <button
        type="button"
        onClick={() => dismiss(item.id)}
        aria-label="Dismiss"
        className="-mr-1 shrink-0 rounded px-1 text-current opacity-60 outline-none hover:opacity-100 focus-visible:ring-2 focus-visible:ring-current/40"
      >
        ✕
      </button>
    </div>
  )
}

/** Fixed stack of active toasts. Mount once near the app root. */
export function Toaster() {
  const toasts = useToastStore((s) => s.toasts)
  if (toasts.length === 0) return null
  return (
    <div className="pointer-events-none fixed bottom-4 left-1/2 z-[60] flex -translate-x-1/2 flex-col items-center gap-2">
      {toasts.map((t) => (
        <ToastItem key={t.id} item={t} />
      ))}
    </div>
  )
}
