<script lang="ts">
	import TrackListing from '$lib/components/groove/TrackListing.svelte';
	import type { PageServerData } from './$types';
	import { getSearchState } from '$lib/search.svelte';
	import type { Action } from 'svelte/action';
	import { SvelteSet as Set } from 'svelte/reactivity';

	interface Props {
		data: PageServerData;
	}

	const search = getSearchState();

	let { data }: Props = $props();

	let container: HTMLDivElement;
	let visibleTracks = $state<Set<string>>(new Set());

	const options: IntersectionObserverInit = {
		// @ts-ignore
		root: container,
		rootMargin: "400px 0px 400px 0px",
		threshold: 0.0,
	};

	const callback: IntersectionObserverCallback = (entries, _observer) => {
		entries.forEach(entry => {
			const hash = entry.target.getAttribute('data-track-hash')!;
			if (entry.isIntersecting) {
				if (!visibleTracks.has(hash)) {
					visibleTracks.add(hash);
				}
			}
			else if (visibleTracks.has(hash)) {
				visibleTracks.delete(hash);
			}
		});
	};

	const observer = new IntersectionObserver(callback, options);

	const observe: Action = (node) => {
		observer.observe(node);
	}

	$effect(() => {
		const firstFewTracks = search.filterTracks(data.tracks).slice(0,40);
		firstFewTracks.forEach(e => {
			visibleTracks.add(e.item.hash);
		});
	});
</script>

<div
	class="grid grid-cols-2 gap-4 sm:grid-cols-4 md:grid-cols-5 lg:grid-cols-6 xl:grid-cols-7 2xl:grid-cols-8"
	bind:this={container}
>
	{#each search.input.length > 0 ? (search.filterTracks(data.tracks).map(r => r.item) ?? []) : data.tracks as track (track.hash)}
		<TrackListing {track} action={observe} hideCover={!visibleTracks.has(track.hash)}/>
	{/each}
</div>
