/**
 * ProRank SEO - AnimatedCounter Component
 *
 * Smooth counting animation for numeric values
 * Supports various formats: integer, decimal, percentage
 *
 * @package ProRank\SEO
 */

import { useState, useEffect, useRef } from '@wordpress/element';

/**
 * Format number based on type
 */
const formatValue = (value, format, decimals = 1) => {
  switch (format) {
    case 'percentage':
      return Math.round(value) + '%';
    case 'decimal':
      return value.toFixed(decimals);
    case 'integer':
    default:
      return Math.round(value).toString();
  }
};

/**
 * AnimatedCounter Component
 */
const AnimatedCounter = ({
  value = 0,
  duration = 1000,
  delay = 0,
  format = 'integer',
  decimals = 1,
  prefix = '',
  suffix = '',
  color,
  className = '',
  onComplete,
  countUp = true,
}) => {
  const [displayValue, setDisplayValue] = useState(countUp ? 0 : value);
  const [isAnimating, setIsAnimating] = useState(false);
  const prevValueRef = useRef(countUp ? 0 : value);
  const animationRef = useRef(null);

  useEffect(() => {
    if (animationRef.current) {
      cancelAnimationFrame(animationRef.current);
    }

    const startValue = prevValueRef.current;
    const endValue = value;
    const startTime = Date.now() + delay;

    if (startValue === endValue) {
      setDisplayValue(endValue);
      return;
    }

    const animate = () => {
      const now = Date.now();

      if (now < startTime) {
        animationRef.current = requestAnimationFrame(animate);
        return;
      }

      const elapsed = now - startTime;
      const progress = Math.min(elapsed / duration, 1);
      const eased = 1 - Math.pow(1 - progress, 3);
      const currentValue = startValue + (endValue - startValue) * eased;

      setDisplayValue(currentValue);
      setIsAnimating(progress < 1);

      if (progress < 1) {
        animationRef.current = requestAnimationFrame(animate);
      } else {
        prevValueRef.current = endValue;
        setDisplayValue(endValue);
        if (onComplete) {
          onComplete(endValue);
        }
      }
    };

    setIsAnimating(true);
    animationRef.current = requestAnimationFrame(animate);

    return () => {
      if (animationRef.current) {
        cancelAnimationFrame(animationRef.current);
      }
    };
  }, [value, duration, delay, onComplete]);

  const formattedValue = formatValue(displayValue, format, decimals);

  const counterStyle = {
    display: 'inline-flex',
    alignItems: 'baseline',
    fontVariantNumeric: 'tabular-nums',
    transition: 'color 150ms ease',
    color: color,
  };

  return (
    <span
      className={'pr:counter ' + (isAnimating ? 'counting ' : '') + className}
      style={counterStyle}
    >
      {prefix}
      <span className="pr:counter-value">{formattedValue}</span>
      {suffix}
    </span>
  );
};

/**
 * AnimatedCounterGroup Component
 */
const AnimatedCounterGroup = ({
  items = [],
  staggerDelay = 100,
  className = '',
}) => {
  const groupStyle = {
    display: 'flex',
    flexDirection: 'column',
    gap: '8px',
  };

  const itemStyle = {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
  };

  const labelStyle = {
    color: 'var(--pr-text-secondary, #6B7280)',
    fontSize: '12px',
  };

  return (
    <div className={'pr:counter-group ' + className} style={groupStyle}>
      {items.map((item, index) => (
        <div key={item.id || index} style={itemStyle}>
          {item.label && (
            <span style={labelStyle}>{item.label}</span>
          )}
          <AnimatedCounter
            value={item.value}
            delay={index * staggerDelay}
            format={item.format}
            prefix={item.prefix}
            suffix={item.suffix}
            color={item.color}
          />
        </div>
      ))}
    </div>
  );
};

export default AnimatedCounter;
export { AnimatedCounterGroup, formatValue };
