import React, { useEffect, useState, useRef } from 'react';
import * as THREE from 'three';
import { useFrame, useThree } from '@react-three/fiber';

interface MaterialAnimatorProps {
    matRef: React.RefObject<THREE.Mesh>;
    material: MaterialSchema;
    speed: number; // units per second
    onAnimationComplete?: () => void;
}

function MaterialAnimator({
    matRef,
    material,
    speed,
    onAnimationComplete
}: MaterialAnimatorProps) {
    const { scene } = useThree();
    const [targetPosition, setTargetPosition] = useState<THREE.Vector3 | null>(null);
    const [isAnimating, setIsAnimating] = useState(false);
    const animationStartTime = useRef<number>(0);
    const startPosition = useRef<THREE.Vector3>(new THREE.Vector3());
    const totalDistance = useRef<number>(0);

    const getWorldPosition = (uuid: string): THREE.Vector3 | null => {
        const obj = scene.getObjectByProperty('uuid', uuid);
        if (!obj) return null;
        const position = new THREE.Vector3();
        obj.getWorldPosition(position);
        return position;
    };

    useEffect(() => {
        if (!material.next?.pointUuid) {
            setTargetPosition(null);
            setIsAnimating(false);
            return;
        }

        const newTarget = getWorldPosition(material.next.pointUuid);
        if (newTarget && matRef.current) {
            startPosition.current.copy(matRef.current.position);
            totalDistance.current = startPosition.current.distanceTo(newTarget);
            animationStartTime.current = performance.now();
            setTargetPosition(newTarget);
            setIsAnimating(true);
        }
    }, [material.next?.pointUuid]);

    useFrame(() => {
        if (!matRef.current || !targetPosition || !isAnimating) return;

        // Calculate exact position based on constant speed
        const elapsed = (performance.now() - animationStartTime.current) / 1000;
        const progress = Math.min(1, (speed * elapsed) / totalDistance.current);
        
        matRef.current.position.lerpVectors(
            startPosition.current,
            targetPosition,
            progress
        );

        // Check if animation is complete
        if (progress >= 1) {
            matRef.current.position.copy(targetPosition);
            setIsAnimating(false);
            onAnimationComplete?.();
        }
    });

    return null;
}

export default React.memo(MaterialAnimator);