import React from "react";

/**
 * useExplorerQuery
 *
 * A tiny, predictable data-fetching hook for the Explorer UI.
 *
 * Design goals:
 * - Keep logic centralized and consistent across all Explorer levels.
 * - Provide stable states: loading / success / error.
 * - Provide a retry mechanism without leaking implementation details to the UI.
 *
 * Non-goals:
 * - This hook does NOT perform routing/redirects.
 *   Routing decisions remain in the UI components for clarity.
 *
 * @template T
 * @param {() => Promise<T>} loadFn - async loader (e.g. apiClient.getYears)
 * @param {any[]} deps - dependencies that define the query identity (e.g. [branch, year])
 * @returns {{
 *   status: "loading"|"success"|"error",
 *   data: T|null,
 *   error: unknown|null,
 *   retry: () => void
 * }}
 */
export function useExplorerQuery(loadFn, deps) {
	const [status, setStatus] = React.useState("loading");
	const [data, setData] = React.useState(null);
	const [error, setError] = React.useState(null);

	// Incrementing this tick triggers a refetch without changing deps.
	const [retryTick, setRetryTick] = React.useState(0);

	const retry = React.useCallback(() => {
		setRetryTick((n) => n + 1);
	}, []);

	React.useEffect(() => {
		let cancelled = false;

		async function run() {
			setStatus("loading");
			setError(null);

			try {
				const result = await loadFn();
				if (cancelled) return;

				setData(result);
				setStatus("success");
			} catch (err) {
				if (cancelled) return;

				setData(null);
				setError(err);
				setStatus("error");
			}
		}

		run();

		return () => {
			cancelled = true;
		};
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [...deps, retryTick]);

	return { status, data, error, retry };
}
