import { command, getRequestEvent, query } from '$app/server';
import { error } from '@sveltejs/kit';

import { stringCoerce } from '$lib/schema/common';
import type { CalibreImport } from '$lib/schema/library';

/** The backend's own message for a failed response, rather than its JSON envelope. */
function detailOf(body: string): string {
	try {
		const parsed = JSON.parse(body);
		return typeof parsed?.detail === 'string' ? parsed.detail : body;
	} catch {
		return body;
	}
}

/**
 * Where an import has got to.
 *
 * A `query` rather than a `command` so it can be refreshed, but it is polled on a timer
 * rather than cached — the answer changes on its own.
 *
 * Starting an import is deliberately **not** here: the archive goes straight to the
 * backend through the proxy, so it never passes through this process. See the import
 * screen's `upload`.
 */
export const getCalibreImport = query(stringCoerce, async (jobId): Promise<CalibreImport> => {
	const { locals } = getRequestEvent();

	const response = await locals.api.get(`/libraries/imports/${jobId}`);

	if (!response.ok) error(response.status, detailOf(await response.text()));

	return await response.json();
});

/**
 * Ask an import to stop after the book it is on.
 *
 * Not an abort: a book abandoned mid-copy would leave files on disk with no row
 * describing them. Whatever it has imported stays imported.
 */
export const cancelCalibreImport = command(stringCoerce, async (jobId): Promise<CalibreImport> => {
	const { locals } = getRequestEvent();

	const response = await locals.api.delete(`/libraries/imports/${jobId}`);

	if (!response.ok) error(response.status, detailOf(await response.text()));

	return await response.json();
});
