import { useCallback } from 'react'
import { useAsyncDebouncer } from './useAsyncDebouncer'
import type { ReactAsyncDebouncerOptions } from './useAsyncDebouncer'
import type { AnyAsyncFunction } from '@tanstack/pacer/types'
/**
* A React hook that creates a debounced version of an async callback function.
* This hook is a convenient wrapper around the `useAsyncDebouncer` hook,
* providing a stable, debounced async function reference for use in React components.
*
* The debounced async function will only execute after the specified wait time has elapsed
* since its last invocation. If called again before the wait time expires, the timer
* resets and starts waiting again. The returned function always returns a promise
* that resolves or rejects with the result of the original async function.
*
* This hook provides a simpler API compared to `useAsyncDebouncer`, making it ideal for basic
* async debouncing needs. However, it does not expose the underlying AsyncDebouncer instance.
*
* For advanced usage requiring features like:
* - Manual cancellation
* - Access to execution/error state
* - Custom useCallback dependencies
*
* Consider using the `useAsyncDebouncer` hook instead.
*
*
* @example
* ```tsx
* // Debounce an async search handler
* const handleSearch = useAsyncDebouncedCallback(async (query: string) => {
* const results = await fetchSearchResults(query);
* return results;
* }, {
* wait: 500 // Wait 500ms between executions
* });
*
* // Use in an input
* handleSearch(e.target.value)}
* />
* ```
*/
export function useAsyncDebouncedCallback(
fn: TFn,
options: ReactAsyncDebouncerOptions,
): (...args: Parameters) => Promise> {
const asyncDebouncedFn = useAsyncDebouncer(fn, options).maybeExecute
return useCallback(
(...args) => asyncDebouncedFn(...args) as Promise>,
[asyncDebouncedFn],
)
}