<script lang="ts">
	import { post } from '$lib/api/client';

	let {
		entityType,
		entityId,
		tripStart = '',
		tripEnd = '',
		onImport,
		onClose
	}: {
		entityType: string;
		entityId: string;
		tripStart?: string;
		tripEnd?: string;
		onImport: () => void;
		onClose: () => void;
	} = $props();

	interface ImmichPhoto {
		id: string;
		thumbnail_url: string;
		filename: string;
		date: string;
	}

	let modal = $state<HTMLDialogElement | null>(null);
	let photos = $state<ImmichPhoto[]>([]);
	let firstLoad = $state(true);
	let loadingMore = $state(false);
	let importing = $state<Set<string>>(new Set());
	let page = $state(1);
	let total = $state(0);
	let hasMore = $state(true);
	let useTripdates = $state(true);
	let scrollContainer = $state<HTMLDivElement | null>(null);

	let initialized = false;
	$effect(() => {
		if (modal && !initialized) {
			initialized = true;
			modal.showModal();
			fetchPhotos(true);
		}
	});

	async function fetchPhotos(reset = false) {
		if (loadingMore) return;

		if (reset) {
			page = 1;
			photos = [];
			hasMore = true;
			firstLoad = true;
		}

		loadingMore = true;
		try {
			const body: any = { page, per_page: 30 };
			if (useTripdates && tripStart) body.start_date = tripStart;
			if (useTripdates && tripEnd) body.end_date = tripEnd;

			const data = await post<{ photos: ImmichPhoto[]; total: number }>('/api/immich/photos', body);
			const newPhotos = data.photos || [];
			total = data.total || 0;
			hasMore = newPhotos.length >= 30;

			if (reset) {
				photos = newPhotos;
			} else {
				photos = photos.concat(newPhotos);
			}
		} catch {
			hasMore = false;
		} finally {
			loadingMore = false;
			firstLoad = false;
		}
	}

	function handleScroll() {
		if (!scrollContainer || loadingMore || !hasMore) return;
		const { scrollTop, scrollHeight, clientHeight } = scrollContainer;
		if (scrollHeight - scrollTop - clientHeight < 200) {
			page++;
			fetchPhotos();
		}
	}

	async function importPhoto(photo: ImmichPhoto) {
		const next = new Set(importing);
		next.add(photo.id);
		importing = next;

		try {
			await post('/api/immich/download', {
				asset_id: photo.id,
				entity_type: entityType,
				entity_id: entityId
			});
			onImport();
		} catch (e) {
			console.error('Import failed:', e);
		}

		const done = new Set(importing);
		done.delete(photo.id);
		importing = done;
	}

	function close() { modal?.close(); onClose(); }

	function toggleDateFilter() {
		useTripdates = !useTripdates;
		fetchPhotos(true);
	}
</script>

<dialog bind:this={modal} class="modal modal-bottom sm:modal-middle" onclose={onClose}>
	<div class="modal-box max-w-3xl max-h-[85vh] flex flex-col">
		<form method="dialog">
			<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">&#x2715;</button>
		</form>

		<h3 class="font-bold text-lg flex items-center gap-2 mb-4 shrink-0">
			<div class="p-2 rounded-xl bg-primary/15">
				<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-primary" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
					<rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/>
				</svg>
			</div>
			Import from Immich
		</h3>

		<!-- Filters -->
		<div class="flex items-center justify-between mb-3 shrink-0">
			<label class="label cursor-pointer gap-2">
				<input type="checkbox" class="toggle toggle-sm toggle-primary" checked={useTripdates} onchange={toggleDateFilter} />
				<span class="label-text text-sm">Trip dates only</span>
			</label>
			<span class="text-xs text-base-content/40">{total} photos</span>
		</div>

		<!-- Content -->
		{#if firstLoad}
			<div class="flex justify-center py-12">
				<span class="loading loading-spinner loading-lg text-primary"></span>
			</div>
		{:else if photos.length === 0}
			<div class="text-center py-12 text-base-content/40">No photos found</div>
		{:else}
			<div
				bind:this={scrollContainer}
				onscroll={handleScroll}
				class="overflow-y-auto flex-1 min-h-0"
			>
				<div class="grid grid-cols-3 sm:grid-cols-4 gap-2 p-1">
					{#each photos as photo (photo.id)}
						<button
							type="button"
							class="relative aspect-square rounded-lg overflow-hidden bg-base-300 hover:ring-2 hover:ring-primary transition-all"
							onclick={() => importPhoto(photo)}
							disabled={importing.has(photo.id)}
						>
							<img
								src="/api/immich/thumb/{photo.id}"
								alt={photo.filename}
								class="absolute inset-0 w-full h-full object-cover"
								loading="lazy"
							/>
							{#if importing.has(photo.id)}
								<div class="absolute inset-0 bg-black/50 flex items-center justify-center">
									<span class="loading loading-spinner loading-sm text-white"></span>
								</div>
							{/if}
						</button>
					{/each}
				</div>

				{#if loadingMore}
					<div class="flex justify-center py-4">
						<span class="loading loading-spinner loading-sm text-primary"></span>
					</div>
				{/if}

				{#if !hasMore}
					<div class="text-center py-3 text-xs text-base-content/30">All photos loaded</div>
				{/if}
			</div>
		{/if}
	</div>
	<form method="dialog" class="modal-backdrop"><button>close</button></form>
</dialog>
