import { useState } from "react";

/**
 *
 * Hook to allow monitoring of an asynchronous operation via a flag.
 *
 * @example
 *
 *  const [asyncHandler, loading] = useAsyncOperation();
 *  ...
 *  const clickHandler = async (): Promise<void> => {
 *      if (onClick) {
 *          await asyncHandler(async () => await onClick());
 *      }
 *  }
 *
 * <Button loading={loading} />
 *
 * @todo modify signature to streamline usage
 *
 * @returns
 * `command` Method to monitor
 * `loading` Flag that updates whether method is actively running
 */
export const useAsyncOperation = (): [
  command: <T>(asyncFunction: (args?: any) => Promise<T>) => Promise<T>,
  loading: boolean,
] => {
  const [isLoading, setIsLoading] = useState<boolean>(false);

  const executionHandler = async <T>(
    asyncFunction: (args?: any) => Promise<T>
  ): Promise<T> => {
    setIsLoading(true);

    try {
      return await asyncFunction();
    } finally {
      setIsLoading(false);
    }
  };

  return [executionHandler, isLoading];
};
