/**
 * WordPress dependencies.
 */
import { useCallback, useRef } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';

/**
 * Internal dependencies.
 */
import { generateRequestId } from '../../utils/helpers';

/**
 * Get a callback function for retrieving search results.
 *
 * @param {string} apiHost API host.
 * @param {string} apiEndpoint API endpoint.
 * @param {string} Authorization Authorization header.
 * @param {Function} onAuthError Function to run when request authentication fails.
 * @param {string} requestIdBase Base of Request IDs.
 * @returns {Function} Function for retrieving search results.
 */
export const useFetchResults = (
	apiHost,
	apiEndpoint,
	Authorization,
	onAuthError,
	requestIdBase = '',
) => {
	const abort = useRef(new AbortController());
	const request = useRef(null);
	const onAuthErrorRef = useRef(onAuthError);

	/**
	 * Get new search results from the API.
	 *
	 * @param {URLSearchParams} urlParams Query arguments.
	 * @returns {Promise} Request promise.
	 */
	const fetchResults = async (urlParams) => {
		const url = `${apiHost}${apiEndpoint}?${urlParams.toString()}`;

		abort.current.abort();
		abort.current = new AbortController();

		const headers = {
			Accept: 'application/json',
			Authorization,
		};

		const requestId = generateRequestId(requestIdBase);

		if (requestId) {
			headers['X-ElasticProbe-Request-ID'] = requestId;
		}

		request.current = fetch(url, {
			signal: abort.current.signal,
			headers,
		})
			.then((response) => {
				if (!response.ok) {
					if (response.status === 401 && onAuthErrorRef.current) {
						onAuthErrorRef.current();
						return '';
					}

					/* translators: Response status code */
					throw new Error(sprintf(__('HTTP %d.', 'elasticprobe'), response.status));
				}

				return response.json();
			})
			.catch((error) => {
				if (error?.name !== 'AbortError') {
					throw error;
				}
			})
			.finally(() => {
				request.current = null;
			});

		return request.current;
	};

	return useCallback(fetchResults, [apiHost, apiEndpoint, Authorization, requestIdBase]);
};
