import { parse } from '@brillout/json-serializer/parse'; /* eslint-disable-line import/extensions */

const postHeaders = {
	mode: 'cors',
	credentials: 'same-origin',
	headers: {
		'Content-Type': 'application/json',
	},
};

function getQuery(data) {
	if (!data) {
		return '';
	}

	const curatedQuery = Object.fromEntries(Object.entries(data).map(([key, value]) => (value === undefined ? null : [key, value])).filter(Boolean));

	return `?${encodeURI(decodeURIComponent(new URLSearchParams(curatedQuery).toString()))}`; // recode so commas aren't encoded
}

export async function get(path, query = {}) {
	const res = await fetch(`/api${path}${getQuery(query)}`);
	const body = parse(await res.text());

	if (res.ok) {
		return body;
	}

	throw new Error(body.statusMessage);
}

export async function post(path, data, { query } = {}) {
	const res = await fetch(`/api${path}${getQuery(query)}`, {
		method: 'POST',
		body: JSON.stringify(data),
		...postHeaders,
	});

	if (res.status === 204) {
		return null;
	}

	const body = parse(await res.text());

	if (res.ok) {
		return body;
	}

	throw new Error(body.statusMessage);
}

export async function patch(path, data, { query } = {}) {
	const res = await fetch(`/api${path}${getQuery(query)}`, {
		method: 'PATCH',
		body: JSON.stringify(data),
		...postHeaders,
	});

	if (res.status === 204) {
		return null;
	}

	const body = parse(await res.text());

	if (res.ok) {
		return body;
	}

	throw new Error(body.statusMessage);
}

export async function del(path, { data, query } = {}) {
	const res = await fetch(`/api${path}${getQuery(query)}`, {
		method: 'DELETE',
		body: JSON.stringify(data),
		...postHeaders,
	});

	if (res.status === 204) {
		return null;
	}

	const body = parse(await res.text());

	if (res.ok) {
		return body;
	}

	throw new Error(body.statusMessage);
}
