// tdd-guard:skip — thin React useState wrapper over the pure
// createUndoableDeleteEngine state machine; engine is fully tested.
//
// App-wide single-slot Undo hook (KAR-629). Lifted from the agenda editor's
// in-place `lastDeleted` state so any list / editor that supports delete can
// offer a consistent "↩ Rückgängig" affordance.
//
//   - The caller captures a snapshot of what was deleted right before
//     calling the actual delete mutation. The snapshot shape is up to the
//     caller (typically `{ index, item }` for in-memory editors,
//     `{ id }` for soft-delete-by-id surfaces).
//
//   - The caller passes an `onUndo` callback that re-inserts the snapshot.
//     The hook does not own the data model — only the
//     "what is the currently undoable delete" state and the auto-dismiss
//     timer.
//
//   - Single slot: a second `captureDelete` replaces the first. Matches the
//     agenda UX ("the last deleted element") and avoids stacked banners.
//
// Pair with `<UndoBanner>` (components/ui/undo-banner.tsx) for a consistent
// look; or render any custom UI off `lastDeleted`.

import { useCallback, useEffect, useRef, useState } from 'react'

import {
  type UndoableDeleteEngine,
  type UndoableDeleteEngineOptions,
  createUndoableDeleteEngine,
} from './undoable-delete-engine'

export type UseUndoableDeleteOptions<T> = Pick<
  UndoableDeleteEngineOptions<T>,
  'onUndo' | 'autoDismissMs'
>

export interface UseUndoableDeleteResult<TSnapshot> {
  /** The last-captured snapshot, or `null` if nothing is currently undoable. */
  lastDeleted: TSnapshot | null
  /** Record a snapshot of what was just deleted. Replaces any previous capture. */
  captureDelete: (snapshot: TSnapshot) => void
  /** Run the caller's onUndo with the captured snapshot and clear it. No-op when nothing captured. */
  undo: () => void
  /** Drop the captured snapshot without calling onUndo. */
  dismiss: () => void
}

export function useUndoableDelete<TSnapshot>(
  opts: UseUndoableDeleteOptions<TSnapshot>,
): UseUndoableDeleteResult<TSnapshot> {
  const { onUndo, autoDismissMs } = opts
  const [lastDeleted, setLastDeleted] = useState<TSnapshot | null>(null)
  const engineRef = useRef<UndoableDeleteEngine<TSnapshot> | null>(null)
  const onUndoRef = useRef(onUndo)

  useEffect(() => {
    onUndoRef.current = onUndo
  }, [onUndo])

  if (engineRef.current === null) {
    engineRef.current = createUndoableDeleteEngine<TSnapshot>({
      onUndo: (snapshot) => onUndoRef.current(snapshot),
      autoDismissMs,
      onChange: () => {
        setLastDeleted(engineRef.current?.getState() ?? null)
      },
    })
  }

  useEffect(() => {
    return () => {
      engineRef.current?.teardown()
    }
  }, [])

  const captureDelete = useCallback((snapshot: TSnapshot) => {
    engineRef.current?.capture(snapshot)
  }, [])

  const undo = useCallback(() => {
    engineRef.current?.undo()
  }, [])

  const dismiss = useCallback(() => {
    engineRef.current?.dismiss()
  }, [])

  return { lastDeleted, captureDelete, undo, dismiss }
}
