export class CounterAnimation {
    static DURATION_MS = 2000;

    init() {
        const counters = document.querySelectorAll('.counter-value[data-target]');
        if (counters.length === 0) return;

        if ('IntersectionObserver' in window) {
            const observer = new IntersectionObserver((entries) => {
                entries.forEach(entry => {
                    if (entry.isIntersecting) {
                        this._animate(entry.target);
                        observer.unobserve(entry.target);
                    }
                });
            }, { threshold: 0.2 });
            counters.forEach(c => observer.observe(c));
        } else {
            counters.forEach(c => this._animate(c));
        }
    }

    _animate(el) {
        const target = Number.parseInt((el.dataset.target || '0').replace(/[^0-9]/g, ''), 10);
        if (Number.isNaN(target)) return;
        CounterAnimation.animateValue(el, target, el.dataset.suffix || '');
    }

    // Reusable easing tween from 0 → target. Callable for stats whose
    // value is only known after an async fetch (no data-target needed).
    static animateValue(el, target, suffix = '') {
        if (!el || Number.isNaN(target)) return;
        const startTime = performance.now();

        const tick = (now) => {
            const progress = Math.min((now - startTime) / CounterAnimation.DURATION_MS, 1);
            const eased = 1 - Math.pow(1 - progress, 3);
            el.textContent = Math.floor(eased * target) + suffix;
            if (progress < 1) requestAnimationFrame(tick);
            else el.textContent = target + suffix;
        };
        requestAnimationFrame(tick);
    }
}
