/**
 * The single apiFetch wrapper every api/ module goes through.
 *
 * Components never import this directly — they call the resource modules,
 * which keeps request shapes in one place per endpoint.
 */

import apiFetch from '@wordpress/api-fetch';
import { __ } from '@wordpress/i18n';
import { getBootstrap } from '../../common';

const { nonce } = getBootstrap();

if ( nonce ) {
	apiFetch.use( apiFetch.createNonceMiddleware( nonce ) );
}

apiFetch.use(
	apiFetch.createRootURLMiddleware( getBootstrap().restRoot || '/wp-json/' )
);

/**
 * Turn any apiFetch rejection into an Error carrying a sentence a human can
 * act on, plus the machine code so callers can branch when they need to.
 *
 * @param {*} error Whatever apiFetch rejected with.
 * @return {Error} Normalised error.
 */
function normalise( error ) {
	const message =
		error?.message ||
		__(
			'Something went wrong and the request could not be completed.',
			'rewind-form-bridge-for-brevo'
		);

	const normalised = new Error( message );
	normalised.code = error?.code || 'rbfb_unknown';
	normalised.status = error?.data?.status || 0;

	return normalised;
}

/**
 * Perform a request against the rbfb/v1 namespace.
 *
 * @param {string} path    Route path, e.g. '/feeds'.
 * @param {Object} options apiFetch options (method, data, ...).
 * @return {Promise<*>} Parsed response body.
 */
export async function request( path, options = {} ) {
	try {
		return await apiFetch( {
			path: `/rbfb/v1${ path }`,
			...options,
		} );
	} catch ( error ) {
		throw normalise( error );
	}
}

export const get = ( path ) => request( path );
export const post = ( path, data ) => request( path, { method: 'POST', data } );
export const put = ( path, data ) => request( path, { method: 'PUT', data } );
export const del = ( path ) => request( path, { method: 'DELETE' } );

/**
 * Build a query string from a filter object, dropping empty values so the
 * REST args schema never sees a blank it has to validate.
 *
 * @param {Object} params Key/value pairs.
 * @return {string} Query string including '?', or an empty string.
 */
export function query( params ) {
	const pairs = Object.entries( params ).filter(
		( [ , value ] ) =>
			value !== '' && value !== null && value !== undefined && value !== 0
	);

	if ( ! pairs.length ) {
		return '';
	}

	return `?${ pairs
		.map( ( [ k, v ] ) => `${ k }=${ encodeURIComponent( v ) }` )
		.join( '&' ) }`;
}
