import { isElementInViewport } from '$lib/utils/viewport';

/**
 * Svelte action that fades in an element when it enters the viewport.
 * Uses IntersectionObserver for efficient viewport detection.
 *
 * If skipIfVisible is set and the element is already visible in the viewport
 * when the action attaches (e.g. a markdown block promoted from unstable
 * during streaming), the fade is skipped entirely to avoid a flash.
 */
export function fadeInView(
	node: HTMLElement,
	options: { duration?: number; y?: number; delay?: number; skipIfVisible?: boolean } = {}
) {
	const { duration = 300, y = 0, delay = 0, skipIfVisible = false } = options;

	if (skipIfVisible && isElementInViewport(node)) {
		return;
	}

	node.style.opacity = '0';
	node.style.transform = `translateY(${y}px)`;
	node.style.transition = `opacity ${duration}ms ease-out, transform ${duration}ms ease-out`;

	$effect(() => {
		const observer = new IntersectionObserver(
			(entries) => {
				for (const entry of entries) {
					if (entry.isIntersecting) {
						setTimeout(() => {
							requestAnimationFrame(() => {
								node.style.opacity = '1';
								node.style.transform = 'translateY(0)';
							});
						}, delay);
						observer.disconnect();
					}
				}
			},
			{ threshold: 0.05 }
		);

		observer.observe(node);

		return () => {
			observer.disconnect();
		};
	});
}
