<script lang="ts">
	import { uploadBookFiles } from '$lib/api';
	import {
		displaySize,
		FileDropZone,
		type FileDropZoneProps
	} from '$lib/components/ui/file-drop-zone';
	import { Button } from '$lib/components/ui/button';
	import * as Field from '$lib/components/ui/field/index.js';

	import { Switch } from '$lib/components/ui/switch/index';
	import { X } from '@lucide/svelte';

	import type { Book } from '$lib/schema';
	import { tick } from 'svelte';
	import { toast } from 'svelte-sonner';

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

	let files = $derived(uploadBookFiles.fields.files.value() ?? []);

	let autoUploadOnDrop = $state(true);
	let formEl = $state<HTMLFormElement>();

	const onUpload: FileDropZoneProps['onUpload'] = async (uploadedFiles) => {
		uploadBookFiles.fields.files.set([...Array.from(files), ...uploadedFiles]);
		if (autoUploadOnDrop && files.length > 0) {
			await tick();
			formEl?.requestSubmit();
		}
	};

	const onFileRejected: FileDropZoneProps['onFileRejected'] = async ({ reason, file }) => {
		toast.error(`${file.name} failed to upload!`, { description: reason });
	};
</script>

<form
	{...uploadBookFiles.enhance(async ({ submit, form }) => {
		try {
			await submit();

			// Check if there are any validation issues
			const issues = uploadBookFiles.fields.allIssues();
			if (issues && issues.length > 0) {
				return;
			}

			// Reset the files field
			uploadBookFiles.fields.files.set([]);
			toast.success('Files successfully added!');
		} catch (error) {
			console.error('Failed to upload files: ', error);
			toast.error('Failed to upload files');
		}
	})}
	bind:this={formEl}
	enctype="multipart/form-data"
	class="flex w-full flex-col gap-2 p-4"
>
	<input {...uploadBookFiles.fields.book_id.as('hidden', book.id)} />

	<FileDropZone
		{onUpload}
		{onFileRejected}
		accept=".pdf,.epub,.mobi,application/pdf,application/epub+zip,application/x-mobipocket-ebook"
		sublabel="Only PDF, EPUB, and MOBI files supported"
	/>
	<input class="hidden" {...uploadBookFiles.fields.files.as('file multiple')} />
	<div class="flex flex-col gap-2">
		{#each files as file, idx}
			<div class="flex place-items-center justify-between gap-2">
				<div class="flex flex-col">
					<span>{file.name}</span>
					<span class="text-xs text-muted-foreground">{displaySize(file.size)}</span>
				</div>
				<Button
					variant="outline"
					size="icon"
					onclick={() => {
						uploadBookFiles.fields.files.set([
							...Array.from(files).slice(0, idx),
							...Array.from(files).slice(idx + 1)
						]);
					}}
				>
					<X />
				</Button>
			</div>
		{/each}
	</div>

	<div class="flex flex-row items-center space-x-2">
		<Switch bind:checked={autoUploadOnDrop} />
		<Field.Label for="auto-upload-on-drop">Auto upload on file drop</Field.Label>
		<Button type="submit" class="ml-auto w-fit">Upload</Button>
	</div>
</form>
