import { invalidate } from '$app/navigation';
import { toast } from 'svelte-sonner';

import { mergeBooks } from '$lib/api/book.remote';
import type { Book } from '$lib/schema';
import type { FieldValue } from './field-spec';

/**
 * Fold `folded` into `survivor`, and tell the reader how it went.
 *
 * Shared because a merge is reachable two ways — the workbench, where the reader
 * resolved the metadata field by field, and the quick action beside it, which
 * takes the survivor's metadata as it stands. Only the `metadata` argument
 * differs, and the invalidation and the wording should not.
 *
 * @returns whether the merge went through; the caller decides what to close or
 * clear, and has no toast of its own to write either way.
 */
export async function mergeInto(
	libraryId: number | string,
	survivor: Book,
	folded: Book[],
	metadata?: Record<string, FieldValue>
): Promise<boolean> {
	try {
		await mergeBooks({
			library_id: libraryId,
			survivor_id: survivor.id,
			merged_ids: folded.map((book) => book.id),
			metadata
		});

		// Both, because a merge is started from the duplicates review and from the
		// library's selection toolbar, and each page depends on a different one.
		await Promise.all([invalidate('app:books'), invalidate('app:duplicate-books')]);

		toast.success(`Merged into “${survivor.title}”`);
		return true;
	} catch (error) {
		console.error('Failed to merge books', error);
		toast.error(error instanceof Error ? error.message : 'Could not merge these books');
		return false;
	}
}
