import apiFetch from '@wordpress/api-fetch';
import { ApiError, readApiErrorBody } from './ApiError';

const REST_NAMESPACE = '/link-checkup/v1';
const ABORT_ERROR_NAME = 'AbortError';

export type QueryParameter = readonly [ string, string | number | undefined ];

export function withQuery(
	path: string,
	queryParameters: readonly QueryParameter[]
): string {
	const searchParameters = new URLSearchParams();

	for ( const [ name, parameterValue ] of queryParameters ) {
		if ( parameterValue !== undefined && parameterValue !== '' ) {
			searchParameters.set( name, String( parameterValue ) );
		}
	}

	const queryText = searchParameters.toString();

	if ( queryText === '' ) {
		return path;
	}

	return `${ path }?${ queryText }`;
}

function isAbort( thrownValue: unknown ): boolean {
	return (
		thrownValue instanceof DOMException &&
		thrownValue.name === ABORT_ERROR_NAME
	);
}

async function answerOf(
	pendingAnswer: Promise< unknown >
): Promise< unknown > {
	try {
		return await pendingAnswer;
	} catch ( thrownValue ) {
		if ( isAbort( thrownValue ) ) {
			throw thrownValue;
		}

		throw new ApiError( readApiErrorBody( thrownValue ) );
	}
}

export function get( path: string, signal: AbortSignal ): Promise< unknown > {
	return answerOf(
		apiFetch( { path: REST_NAMESPACE + path, method: 'GET', signal } )
	);
}

export function post( path: string, requestBody?: object ): Promise< unknown > {
	return answerOf(
		apiFetch( {
			path: REST_NAMESPACE + path,
			method: 'POST',
			data: requestBody,
		} )
	);
}
