import { useEffect, useRef, useState } from 'react';
import './FlipDigit.css';

interface FlipDigitProps {
  value: number;
  size: number;
}

export function FlipDigit({ value, size }: FlipDigitProps) {
  // Background top value (updates immediately at animation start)
  const [bgTopValue, setBgTopValue] = useState(value);
  // Background bottom value (updates after bottom flip completes)
  const [bgBottomValue, setBgBottomValue] = useState(value);
  // Flip top value (holds old value at animation start)
  const [flipTopValue, setFlipTopValue] = useState(value);
  // Flip bottom value (holds new value)
  const [flipBottomValue, setFlipBottomValue] = useState<number | null>(null);

  const animating = useRef(false);

  const halfHeight = size * 0.5;
  const cardWidth = size * 0.75;
  const fontSize = size * 0.75;

  // Text offset for vertical alignment
  const topTextOffset = halfHeight * 0.75;
  const bottomTextOffset = -halfHeight * 0.75;

  // Animation state
  const [topRotation, setTopRotation] = useState(0);
  const [bottomRotation, setBottomRotation] = useState(-90);
  const [isAnimating, setIsAnimating] = useState(false);

  // Finish animation
  const finishAnimation = () => {
    setIsAnimating(false);

    requestAnimationFrame(() => {
      setTopRotation(0);
      setBottomRotation(-90);
      setFlipBottomValue(null);
      animating.current = false;
    });
  };

  // Start bottom animation after top completes
  const startBottomAnimation = (targetValue: number) => {
    // 上半片翻转完成后，更新上半翻转片的值为新值
    // 这样当 finishAnimation 重置 rotation 时，上半翻转片显示正确的值
    setFlipTopValue(targetValue);

    // 第二阶段：下半片从-90°向下翻转90°到0°
    requestAnimationFrame(() => {
      setBottomRotation(0);
    });

    // 下半片翻转完成后，背景下半更新为新值
    setTimeout(() => {
      setBgBottomValue(targetValue);
      setTimeout(() => {
        finishAnimation();
      }, 50);
    }, 300);
  };

  // When value changes, trigger animation
  useEffect(() => {
    if (value !== bgTopValue && !animating.current) {
      animating.current = true;

      // Save current value as flip top value
      setFlipTopValue(bgTopValue);
      // Set flip bottom value to new value
      setFlipBottomValue(value);
      // Update bgTop immediately (revealed when top flips away)
      setBgTopValue(value);

      // First, ensure transition is disabled before resetting rotation
      setIsAnimating(false);

      // Reset rotation states instantly (without transition)
      setTopRotation(0);
      setBottomRotation(-90);

      // Wait for browser to apply the reset (without transition)
      requestAnimationFrame(() => {
        // Now enable transition for the actual animation
        setIsAnimating(true);

        // Wait one more frame to ensure transition is enabled
        requestAnimationFrame(() => {
          // Start top animation: flip from 0° to 90°
          setTopRotation(90);
        });
      });

      // After top animation completes, start bottom animation
      setTimeout(() => {
        startBottomAnimation(value);
      }, 300);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [value, bgTopValue]);

  const containerStyle = {
    width: `${cardWidth}px`,
    height: `${size}px`,
  };

  const halfHeightStyle = {
    height: `${halfHeight}px`,
  };

  const topTextStyle = {
    fontSize: `${fontSize}px`,
    transform: `translateY(${topTextOffset}px)`,
  };

  const bottomTextStyle = {
    fontSize: `${fontSize}px`,
    transform: `translateY(${bottomTextOffset}px)`,
  };

  const topFlipStyle = {
    height: `${halfHeight}px`,
    transform: `rotateX(${topRotation}deg)`,
  };

  const bottomFlipStyle = {
    height: `${halfHeight}px`,
    transform: `rotateX(${bottomRotation}deg)`,
  };

  const centerLineStyle = {
    top: `${halfHeight - 0.5}px`,
  };

  return (
    <div className="flip-digit-container" style={containerStyle}>
      {/* Background top - shows new value's top half */}
      <div className="flip-digit-bg-top" style={halfHeightStyle}>
        <span className="flip-digit-text flip-digit-top-text" style={topTextStyle}>
          {bgTopValue}
        </span>
      </div>

      {/* Background bottom - shows old value's bottom half */}
      <div className="flip-digit-bg-bottom" style={halfHeightStyle}>
        <span className="flip-digit-text flip-digit-bottom-text" style={bottomTextStyle}>
          {bgBottomValue}
        </span>
      </div>

      {/* Top flip flap - shows old value's top half, flips down */}
      <div
        className="flip-digit-flip-top"
        style={{
          ...halfHeightStyle,
          ...topFlipStyle,
          transition: isAnimating ? 'transform 300ms ease-in' : 'none',
        }}
      >
        <span className="flip-digit-text flip-digit-top-text" style={topTextStyle}>
          {flipTopValue}
        </span>
      </div>

      {/* Bottom flip flap - shows new value's bottom half, flips down */}
      {flipBottomValue !== null && (
        <div
          className="flip-digit-flip-bottom"
          style={{
            ...halfHeightStyle,
            ...bottomFlipStyle,
            transition: isAnimating ? 'transform 300ms ease-out' : 'none',
          }}
        >
          <span className="flip-digit-text flip-digit-bottom-text" style={bottomTextStyle}>
            {flipBottomValue}
          </span>
        </div>
      )}

      {/* Center divider line */}
      <div className="flip-digit-center-line" style={centerLineStyle} />
    </div>
  );
}
