import { useCallback, useEffect, useMemo, useRef, useState } from "react";

export function useQuery(key, fetcher, options = {}) {
  const enabled = options.enabled ?? true;

  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(Boolean(enabled));
  const [error, setError] = useState(null);

  const keyStr = useMemo(() => JSON.stringify(key ?? []), [key]);
  const fetcherRef = useRef(fetcher);
  fetcherRef.current = fetcher;

  const run = useCallback(async () => {
    if (!enabled) return;
    setLoading(true);
    setError(null);
    try {
      const res = await fetcherRef.current();
      setData(res);
      return res;
    } catch (e) {
      setError(e);
      throw e;
    } finally {
      setLoading(false);
    }
  }, [enabled]);

  useEffect(() => {
    if (!enabled) return;
    run();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [keyStr, enabled]);

  return {
    data,
    loading,
    error,
    refetch: run,
  };
}
