<script lang="ts">
	import type { Book } from '$lib/schema';
	import GeneratedCover from './generated-cover.svelte';

	let {
		book,
		height = 220,
		class: className = ''
	}: { book: Book; height?: number; class?: string } = $props();

	let failed = $state(false);

	const src = $derived(book.cover_image ? `/api/${book.cover_image}` : null);
</script>

<!--
	Covers arrive at whatever size the EPUB or PDF carried — the backend converts
	to WebP without resizing. This shows the whole cover at its own aspect ratio:
	the height is fixed so callers can rely on it for layout, and the width falls
	out of the image. Nothing is cropped and nothing is stretched.

	The wrapper reserves a minimum width so the text beside it only settles by a
	few pixels once the image loads. Removing that last reflow needs the intrinsic
	dimensions stored at ingest.

	That reservation is proportional to the height, not a fixed value: a 2:3 cover
	is 0.67x its height wide, so 0.6x reserves almost all of it without ever
	overshooting. A flat minimum would make the wrapper — and any link wrapping
	it — far wider than a small cover.
-->
<span
	class="inline-flex shrink-0 items-end {className}"
	style="height: {height}px; min-width: {Math.round(height * 0.6)}px;"
>
	{#if src && !failed}
		<!--
			The rounded box lives on this wrapper, not the image, so anything
			overlaid on the cover — the progress bar — is clipped to the same
			silhouette instead of squaring off its corners. The shadow moves here
			too, since overflow-hidden would otherwise clip the image's own.
		-->
		<span class="relative h-full overflow-hidden rounded-sm shadow-lg">
			<img
				{src}
				alt="Cover of {book.title}"
				onerror={() => (failed = true)}
				class="h-full w-auto object-contain"
				style="max-width: {Math.round(height * 0.95)}px;"
			/>

			{#if book.progress?.percentage}
				<span class="absolute inset-x-0 bottom-0 h-1 bg-black/30">
					<span
						class="block h-full {book.progress.completed ? 'bg-success' : 'bg-flag'}"
						style="width: {Math.min(100, Math.round(book.progress.percentage * 100))}%;"
					></span>
				</span>
			{/if}
		</span>
	{:else}
		<!-- No cover on record, or the file is missing. Draw one. -->
		<span
			class="h-full overflow-hidden rounded-sm shadow-lg"
			style="width: {Math.round(height * 0.66)}px;"
		>
			<GeneratedCover {book} />
		</span>
	{/if}
</span>
