import { useEffect, useState, useRef } from 'react';
import tokenizeWithMarkdown from '../utils/markdownTokenizer';
const useAnimatedText = ({ text, allContentReceived = false, enabled = true, tokenizeMarkdown = false }) => {
    const [cursor, setCursor] = useState(0); // End pointer
    const [startingCursor, setStartingCursor] = useState(0); // animation starting point
    const [prevText, setPrevText] = useState(text);
    const [isAnimationDone, setIsAnimationDone] = useState(false);
    const allContentReceivedRef = useRef(allContentReceived);
    allContentReceivedRef.current = allContentReceived;
    // Tokenize text based on markdown flag
    const getTokens = (inputText) => {
        if (tokenizeMarkdown) {
            return tokenizeWithMarkdown(inputText);
        }
        return inputText.split('');
    };
    // A new chunk has arrived
    if (prevText !== text) {
        setPrevText(text);
        setStartingCursor(text.startsWith(prevText) ? cursor : 0);
        setIsAnimationDone(false);
    }
    useEffect(() => {
        // If streaming is disabled just return the whole chunk back
        if (!enabled) {
            setCursor(getTokens(text).length);
            setIsAnimationDone(true);
            return;
        }
        const tokens = getTokens(text);
        const targetLength = tokens.length;
        const charactersToAnimate = targetLength - startingCursor;
        // If there are no more characters to animate
        if (charactersToAnimate <= 0) {
            setCursor(targetLength);
            // Only set animation done if we have all content AND no more characters to animate
            if (allContentReceivedRef.current) {
                setIsAnimationDone(true);
            }
            return;
        }
        let intervalId;
        let startTime;
        let isStopped = false;
        let currentSpeed = 50; // Start with normal speed
        let lastCursor = startingCursor;
        const processTextAnimation = () => {
            if (isStopped)
                return;
            const currentTime = performance.now();
            if (!startTime) {
                startTime = currentTime;
            }
            // When we have all content with us, speed up streaming animation
            const targetSpeed = allContentReceivedRef.current ? 150 : 50;
            // Smoothly transition to target speed
            const speedDiff = targetSpeed - currentSpeed;
            currentSpeed += speedDiff * 0.1; // Smooth transition
            const elapsed = currentTime - startTime;
            const timeStep = elapsed / 1000;
            // Calculate how many characters we should have shown by now
            const expectedCursor = Math.min(startingCursor + timeStep * currentSpeed, targetLength);
            const newCursor = Math.min(Math.floor(expectedCursor), targetLength);
            // Skip update if the cursor is at the same token
            if (newCursor !== lastCursor) {
                setCursor(newCursor);
                lastCursor = newCursor;
            }
            // End condition - stop when we reach the target
            if (newCursor >= targetLength && allContentReceivedRef.current) {
                setIsAnimationDone(true);
                return;
            }
            // Continue animation if not done
            if (newCursor < targetLength || !allContentReceivedRef.current) {
                // Use adaptive timing based on content state and visibility
                const interval = allContentReceivedRef.current ? 20 : 50; // Faster when complete
                intervalId = setTimeout(processTextAnimation, interval);
            }
        };
        // Start the animation with initial delay
        intervalId = setTimeout(processTextAnimation, 16);
        return () => {
            isStopped = true;
            if (intervalId) {
                clearTimeout(intervalId);
            }
        };
    }, [startingCursor, text, tokenizeMarkdown]);
    return {
        text: getTokens(text).slice(0, cursor).join(''),
        isAnimationDone
    };
};
export default useAnimatedText;
//# sourceMappingURL=useAnimatedText.js.map