<script lang="ts">
	import { tweened } from 'svelte/motion';
	import { cubicOut } from 'svelte/easing';
	import { onMount } from 'svelte';

	interface Props {
		value: number;
		duration?: number;
		prefix?: string;
		suffix?: string;
		format?: (value: number) => string;
	}

	let {
		value,
		duration = 2000,
		prefix = '',
		suffix = '',
		format = (val: number) => Math.floor(val).toLocaleString()
	}: Props = $props();

	const displayValue = tweened(0, {
		duration,
		easing: cubicOut
	});

	let hasAnimated = false;
	let containerElement: HTMLElement;

	onMount(() => {
		// Use Intersection Observer to start animation when visible
		const observer = new IntersectionObserver(
			(entries) => {
				for (const entry of entries) {
					if (entry.isIntersecting && !hasAnimated) {
						hasAnimated = true;
						displayValue.set(value);
					}
				}
			},
			{ threshold: 0.1 }
		);

		if (containerElement) {
			observer.observe(containerElement);
		}

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

	// Update the target value if it changes after initial animation
	$effect(() => {
		if (hasAnimated) {
			displayValue.set(value);
		}
	});
</script>

<span bind:this={containerElement} class="tabular-nums">
	{prefix}{format($displayValue)}{suffix}
</span>
