<script lang="ts">
	import { invalidateAll } from '$app/navigation';

	interface Props {
		entryId: string;
		onUploadStart?: () => void;
		onUploadComplete?: (imageId: string) => void;
		onUploadError?: (error: string) => void;
	}

	let { entryId, onUploadStart, onUploadComplete, onUploadError }: Props = $props();

	let isDragging = $state(false);
	let isUploading = $state(false);
	let previewUrl: string | null = $state(null);
	let fileInput: HTMLInputElement;

	function handleDragOver(e: DragEvent) {
		e.preventDefault();
		isDragging = true;
	}

	function handleDragLeave(e: DragEvent) {
		e.preventDefault();
		isDragging = false;
	}

	function handleDrop(e: DragEvent) {
		e.preventDefault();
		isDragging = false;

		const file = e.dataTransfer?.files[0];
		if (file && file.type.startsWith('image/')) {
			uploadFile(file);
		}
	}

	function handleFileSelect(e: Event) {
		const input = e.target as HTMLInputElement;
		const file = input.files?.[0];
		if (file) {
			uploadFile(file);
		}
	}

	async function uploadFile(file: File) {
		// Validate image type
		if (!file.type.startsWith('image/')) {
			onUploadError?.('File must be an image');
			return;
		}

		// Create optimistic preview
		previewUrl = URL.createObjectURL(file);
		onUploadStart?.();
		isUploading = true;

		try {
			const formData = new FormData();
			formData.append('image', file);
			formData.append('entryId', entryId);

			const response = await fetch('?/uploadImage', {
				method: 'POST',
				body: formData
			});

			const result = await response.json();

			if (result.type === 'failure') {
				const errorMsg = result.data?.error || 'Upload failed';
				onUploadError?.(errorMsg);
			} else if (result.type === 'success') {
				onUploadComplete?.(result.data?.imageId);
				await invalidateAll();
			}
		} catch (err) {
			console.error('Upload error:', err);
			onUploadError?.('Network error during upload');
		} finally {
			// Cleanup
			if (previewUrl) {
				URL.revokeObjectURL(previewUrl);
				previewUrl = null;
			}
			isUploading = false;
			// Reset file input
			if (fileInput) {
				fileInput.value = '';
			}
		}
	}

	function handleKeydown(e: KeyboardEvent) {
		if (e.key === 'Enter' || e.key === ' ') {
			e.preventDefault();
			fileInput?.click();
		}
	}
</script>

<div
	class="relative border-2 border-dashed rounded-lg p-4 text-center transition-colors cursor-pointer min-h-[100px] flex items-center justify-center {isDragging
		? 'border-blue-500 bg-blue-50'
		: 'border-gray-300 hover:border-gray-400'}"
	ondragover={handleDragOver}
	ondragleave={handleDragLeave}
	ondrop={handleDrop}
	role="button"
	tabindex="0"
	onclick={() => fileInput?.click()}
	onkeydown={handleKeydown}
>
	<input
		bind:this={fileInput}
		type="file"
		accept="image/*"
		onchange={handleFileSelect}
		class="hidden"
	/>

	{#if isUploading}
		<div class="flex flex-col items-center gap-2">
			{#if previewUrl}
				<img src={previewUrl} alt="Preview" class="w-16 h-16 object-cover rounded opacity-50" />
			{/if}
			<div class="flex items-center gap-2 text-gray-500">
				<svg
					class="w-5 h-5 animate-spin"
					xmlns="http://www.w3.org/2000/svg"
					fill="none"
					viewBox="0 0 24 24"
				>
					<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"
					></circle>
					<path
						class="opacity-75"
						fill="currentColor"
						d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
					></path>
				</svg>
				<span class="text-sm">Uploading...</span>
			</div>
		</div>
	{:else}
		<div class="flex flex-col items-center gap-2 text-gray-500">
			<svg
				class="w-8 h-8"
				xmlns="http://www.w3.org/2000/svg"
				fill="none"
				viewBox="0 0 24 24"
				stroke="currentColor"
			>
				<path
					stroke-linecap="round"
					stroke-linejoin="round"
					stroke-width="2"
					d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
				/>
			</svg>
			<span class="text-sm">Drop image or click to upload</span>
		</div>
	{/if}
</div>
