<script lang="ts">
	import { tick, untrack } from 'svelte';
	import { toast } from 'svelte-sonner';

	import { updateBookCover } from '$lib/api';
	import type { Book } from '$lib/schema';
	import BookImage from '$lib/components/view/book-image.svelte';
	import { FileDropZone, type FileDropZoneProps } from '$lib/components/ui/file-drop-zone/index.js';

	let { book }: { book: Book } = $props();

	let formEl = $state<HTMLFormElement>();
	// Seeded once per mount — see the key in edit-book.svelte
	let coverImagePreview = $state<string>(untrack(() => `/api/${book.cover_image}`));

	const onUpload: FileDropZoneProps['onUpload'] = async (uploadedFiles) => {
		updateBookCover.fields.file.set(uploadedFiles[0]);
		updateCoverPreview();
		await tick();
		formEl?.requestSubmit();
	};

	function updateCoverPreview() {
		const file = updateBookCover.fields.file.value();
		if (file && file.type.startsWith('image/')) {
			const reader = new FileReader();
			reader.onloadend = () => {
				coverImagePreview = reader.result as string;
			};
			reader.readAsDataURL(file);
		}
	}

	const onFileRejected: FileDropZoneProps['onFileRejected'] = async ({ reason, file }) => {
		toast.error(`${file.name} was not used`, { description: reason });
	};

	$effect(() => {
		book;
		untrack(() => {
			updateBookCover.fields.book_id.set(book.id);
		});
	});
</script>

<section class="flex min-w-0 flex-col gap-2">
	<h3 class="font-mono text-[10px] tracking-widest text-muted-foreground uppercase">Cover</h3>

	<BookImage src={coverImagePreview} class="w-full rounded-md border" />

	<form
		bind:this={formEl}
		{...updateBookCover.enhance(async ({ submit, element }) => {
			try {
				await submit();
				element.reset();
				// Deliberately does not close the dialog. The cover is one panel of a
				// larger form now, and closing here would throw away metadata edits
				// the reader has not saved yet.
				toast.success('Cover updated');
			} catch (error) {
				console.error('Failed to update book cover: ', error);
				toast.error('Failed to update the cover');
			}
		})}
		enctype="multipart/form-data"
		class="flex flex-col gap-2"
	>
		<input class="hidden" {...updateBookCover.fields.book_id.as('text')} />
		<input class="hidden" {...updateBookCover.fields.file.as('file')} />

		<FileDropZone
			{onUpload}
			{onFileRejected}
			accept=".jpeg,.jpg,.png,.webp,image/*"
			label="Replace cover"
			sublabel="JPEG, PNG or WEBP"
			maxFiles={1}
			fileCount={updateBookCover.fields.file.value() ? 1 : 0}
		/>
	</form>
</section>
