'use client';

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

/**
 * Runs an async action at most once at a time (sync re-entry guard via ref).
 * Use for API mutations from buttons/controls that are not the shared Button,
 * or when several controls share one pending flag.
 */
export function useAsyncAction() {
  const [pending, setPending] = useState(false);
  const pendingRef = useRef(false);

  const run = useCallback(async <T,>(fn: () => Promise<T>): Promise<T | undefined> => {
    if (pendingRef.current) return undefined;
    pendingRef.current = true;
    setPending(true);
    try {
      return await fn();
    } finally {
      pendingRef.current = false;
      setPending(false);
    }
  }, []);

  return { pending, run };
}

/**
 * Same as useAsyncAction, but tracks which row/id is in flight so list UIs
 * can disable sibling actions while one mutation runs.
 */
export function useAsyncActionById() {
  const [pendingId, setPendingId] = useState<string | null>(null);
  const pendingIdRef = useRef<string | null>(null);

  const run = useCallback(async <T,>(id: string, fn: () => Promise<T>): Promise<T | undefined> => {
    if (pendingIdRef.current) return undefined;
    pendingIdRef.current = id;
    setPendingId(id);
    try {
      return await fn();
    } finally {
      pendingIdRef.current = null;
      setPendingId(null);
    }
  }, []);

  return { pendingId, run };
}
