<script lang="ts">
	import { onMount } from 'svelte';
	import type { CounterElement } from '../types';

	interface Props { element: CounterElement; slideId: string; }
	let { element, slideId }: Props = $props();

	let displayValue = $state(0);
	let animationFrame: number | null = null;

	function animateCounter() {
		const startTime = performance.now();
		const startVal = element.startValue;
		const endVal = element.endValue;
		const dur = element.duration;

		function tick() {
			const elapsed = performance.now() - startTime;
			const progress = Math.min(elapsed / dur, 1);
			const eased = 1 - Math.pow(1 - progress, 3);
			displayValue = startVal + (endVal - startVal) * eased;
			if (progress < 1) animationFrame = requestAnimationFrame(tick);
		}

		if (animationFrame) cancelAnimationFrame(animationFrame);
		setTimeout(() => { displayValue = startVal; animationFrame = requestAnimationFrame(tick); }, 200);
	}

	onMount(() => { animateCounter(); return () => { if (animationFrame) cancelAnimationFrame(animationFrame); }; });
	$effect(() => { if (slideId) animateCounter(); });

	function formatValue(val: number): string {
		switch (element.counterType) {
			case 'letter': return String.fromCharCode(65 + (Math.round(val) % 26));
			case 'percentage': return val.toFixed(element.decimals) + '%';
			case 'currency': return '$' + val.toLocaleString('en-US', { minimumFractionDigits: element.decimals, maximumFractionDigits: element.decimals });
			default: return element.decimals === 0 ? Math.round(val).toLocaleString() : val.toFixed(element.decimals);
		}
	}

	const formattedValue = $derived(element.prefix + formatValue(displayValue) + element.suffix);
</script>

<div
	class="counter"
	style:font-size="{element.fontSize}px"
	style:font-weight={element.fontWeight}
	style:font-family="'{element.fontFamily}', sans-serif"
	style:color={element.color}
	style:background-color={element.backgroundColor}
	style:padding="{element.padding}px"
	style:border-radius="{element.borderRadius}px"
	style:text-align={element.textAlign}
>
	{formattedValue}
</div>

<style>
	.counter {
		width: 100%; height: 100%; display: flex; align-items: center;
		justify-content: center; box-sizing: border-box; overflow: hidden;
		white-space: nowrap;
	}
</style>
