<script lang="ts">
	import ImagePlus from '@lucide/svelte/icons/image-plus';
	import X from '@lucide/svelte/icons/x';
	import { onDestroy } from 'svelte';

	let {
		name = 'image',
		required = false,
		disabled = false,
		onSelect = null,
		previewUrl = null
	}: {
		name?: string;
		required?: boolean;
		disabled?: boolean;
		onSelect?: ((file: File) => void) | null;
		previewUrl?: string | null;
	} = $props();

	let inputEl = $state<HTMLInputElement | null>(null);
	let dragging = $state(false);

	// derived value instead of initializing from required
	let canRemove = $derived(!required);

	function openFileDialog() {
		if (!disabled) {
			inputEl?.click();
		}
	}

	function handleFiles(files: FileList | null) {
		if (!files || files.length === 0) return;

		const selected = files[0];
		if (!selected.type.startsWith('image/')) return;

		cleanupPreview();
		previewUrl = URL.createObjectURL(selected);

		if (onSelect) onSelect(selected);
	}

	function onInputChange(e: Event) {
		const target = e.target as HTMLInputElement;
		handleFiles(target.files);
	}

	function onDrop(e: DragEvent) {
		e.preventDefault();
		dragging = false;
		if (disabled) return;
		handleFiles(e.dataTransfer?.files ?? null);
	}

	function cleanupPreview() {
		if (previewUrl) {
			URL.revokeObjectURL(previewUrl);
			previewUrl = null;
		}
	}

	onDestroy(cleanupPreview);
</script>

<div>
	<input
		bind:this={inputEl}
		type="file"
		name={name}
		accept="image/*"
		required={required}
		disabled={disabled}
		capture="environment"
		onchange={onInputChange}
		formaction="/item?/describe"
		hidden
	/>

	<button
		class="dropzone"
		class:has-image={!!previewUrl}
		class:dragging={dragging}
		onclick={openFileDialog}
		ondragover={(e) => {e.preventDefault(); dragging = !disabled;}}
		ondragleave={() => (dragging = false)}
		ondrop={onDrop}
		type="button"
	>
		{#if previewUrl}
			<img src={previewUrl} alt="Selected preview" />

			<div class="overlay">
				<ImagePlus size={24} />
				<span>Replace image</span>
			</div>
		{:else}
			<div class="placeholder py-4">
				<ImagePlus size={32} />
				<p>
					Click or drag an image here
					<span class="text-error">{required ? '*' : ''}</span>
				</p>
			</div>
		{/if}
	</button>

	{#if previewUrl && canRemove}
		<button
			class="hover:text-destructive p-2"
			onclick={cleanupPreview}
			type="button"
		>
			<X size={24} class="inline" />
			<span class="inline align-middle">Remove image</span>
		</button>
	{/if}
</div>

<style>
    .dropzone {
        position: relative;
        width: 100%;
        max-height: 200px;
        min-height: 80px;
        border-radius: 12px;
        border: 2px dashed var(--border);
        cursor: pointer;
        display: flex;
        align-items: center;
        justify-content: center;
        overflow: hidden;
        transition: border-color 0.2s, background 0.2s;
    }

    .dropzone.dragging {
        border-color: var(--primary);
        background: var(--muted);
    }

    .placeholder {
        text-align: center;
        color: var(--muted-foreground);
        display: flex;
        flex-direction: column;
        gap: 0.5rem;
        align-items: center;
    }

    img {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

    .overlay {
        position: absolute;
        inset: 0;
        background: rgba(0, 0, 0, 0.55);
        color: white;
        display: flex;
        flex-direction: column;
        gap: 0.4rem;
        align-items: center;
        justify-content: center;
        opacity: 0;
        transition: opacity 0.2s;
        pointer-events: none;
        text-align: center;
        font-size: 0.9rem;
    }

    .has-image:hover .overlay {
        opacity: 1;
    }

    .has-image:hover img {
        filter: brightness(0.8);
    }
</style>
