import { useState, useEffect, useRef } from 'react';

interface UseCountUpOptions {
    end: number;
    duration?: number;
    decimals?: number;
    startOnInView?: boolean;
}

export const useCountUp = ({ end, duration = 2000, decimals = 0, startOnInView = true }: UseCountUpOptions) => {
    const [count, setCount] = useState(0);
    const [isVisible, setIsVisible] = useState(false);
    const [hasStarted, setHasStarted] = useState(false);
    const elementRef = useRef<HTMLElement>(null);

    // Intersection Observer for triggering animation when element comes into view
    useEffect(() => {
        if (!startOnInView) {
            setHasStarted(true);
            return;
        }

        const observer = new IntersectionObserver(
            ([entry]) => {
                if (entry.isIntersecting && !hasStarted) {
                    setIsVisible(true);
                    setHasStarted(true);
                }
            },
            { threshold: 0.1 }
        );

        if (elementRef.current) {
            observer.observe(elementRef.current);
        }

        return () => observer.disconnect();
    }, [startOnInView, hasStarted]);

    // Counter animation
    useEffect(() => {
        if (!hasStarted) return;

        let startTime: number;
        let animationFrame: number;

        const animate = (currentTime: number) => {
            if (!startTime) startTime = currentTime;
            const progress = Math.min((currentTime - startTime) / duration, 1);

            // Easing function for smooth animation
            const easeOutCubic = 1 - Math.pow(1 - progress, 3);
            const currentCount = end * easeOutCubic;

            setCount(currentCount);

            if (progress < 1) {
                animationFrame = requestAnimationFrame(animate);
            }
        };

        animationFrame = requestAnimationFrame(animate);

        return () => {
            if (animationFrame) {
                cancelAnimationFrame(animationFrame);
            }
        };
    }, [end, duration, hasStarted]);

    const formattedCount = count.toFixed(decimals);

    return { count: formattedCount, elementRef };
};

// Utility function to parse numbers from strings like "150+", "99.9%", "<2min"
export const parseNumberFromString = (value: string): number => {
    const numericMatch = value.match(/(\d+\.?\d*)/);
    return numericMatch ? parseFloat(numericMatch[1]) : 0;
};

// Utility function to format the final value with original suffix/prefix
export const formatWithOriginalString = (originalValue: string, animatedNumber: string): string => {
    const numericMatch = originalValue.match(/(\d+\.?\d*)/);
    if (!numericMatch) return originalValue;

    const originalNumber = numericMatch[1];
    return originalValue.replace(originalNumber, animatedNumber);
};
