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

/**
 * Helper function to find the first sentence in text
 * A sentence ends with . ! or ? followed by a space or end of string
 */
const findFirstSentence = (text) => {
    const sentenceEndRegex = /[.!?]\s/;
    const match = text.match(sentenceEndRegex);
    if (!match || match.index === undefined) {
        // No sentence boundary found, treat entire text as first sentence
        return { firstSentence: text, remaining: '' };
    }
    const endIndex = match.index + match[0].length;
    const firstSentence = text.substring(0, endIndex).trim();
    const remaining = text.substring(endIndex).trim();
    return { firstSentence, remaining };
};
/**
 * Custom hook for word-by-word typing animation
 * Shows first sentence immediately to establish bubble width,
 * then animates remaining text word-by-word
 *
 * @example
 * ```tsx
 * const { displayText, isComplete } = useTypewriter({
 *   text: "Hello world. This is a typing animation",
 *   speed: 100,
 *   enabled: true
 * });
 *
 * return <div>{displayText}</div>;
 * ```
 */
const useTypewriter = ({ text, speed = 100, enabled = true, onComplete, }) => {
    const [displayText, setDisplayText] = useState('');
    const [isComplete, setIsComplete] = useState(false);
    const firstSentenceRef = useRef('');
    const remainingWordsRef = useRef([]);
    const currentIndexRef = useRef(0);
    const timerRef = useRef(undefined);
    const onCompleteRef = useRef(onComplete);
    onCompleteRef.current = onComplete;
    // Split text into first sentence and remaining words
    useEffect(() => {
        var _a;
        if (!text) {
            firstSentenceRef.current = '';
            remainingWordsRef.current = [];
            setDisplayText('');
            setIsComplete(true);
            return;
        }
        const { firstSentence, remaining } = findFirstSentence(text);
        firstSentenceRef.current = firstSentence;
        remainingWordsRef.current = remaining ? remaining.split(' ') : [];
        currentIndexRef.current = 0;
        // Show first sentence immediately
        setDisplayText(firstSentence);
        setIsComplete(false);
        // If animation is disabled or no remaining text, show full text immediately
        if (!enabled || !remaining) {
            setDisplayText(text);
            setIsComplete(true);
            (_a = onCompleteRef.current) === null || _a === void 0 ? void 0 : _a.call(onCompleteRef);
        }
    }, [text, enabled]);
    // Animate remaining words after first sentence
    useEffect(() => {
        if (!enabled || isComplete || remainingWordsRef.current.length === 0) {
            return;
        }
        const animateNextWord = () => {
            var _a, _b;
            const currentIndex = currentIndexRef.current;
            const remainingWords = remainingWordsRef.current;
            const firstSentence = firstSentenceRef.current;
            if (currentIndex >= remainingWords.length) {
                setIsComplete(true);
                (_a = onCompleteRef.current) === null || _a === void 0 ? void 0 : _a.call(onCompleteRef);
                return;
            }
            // Build display text: first sentence + animated remaining words
            const animatedWords = remainingWords.slice(0, currentIndex + 1);
            const newDisplayText = firstSentence + (firstSentence ? ' ' : '') + animatedWords.join(' ');
            setDisplayText(newDisplayText);
            currentIndexRef.current += 1;
            // Schedule next word
            if (currentIndex + 1 < remainingWords.length) {
                timerRef.current = setTimeout(animateNextWord, speed);
            }
            else {
                setIsComplete(true);
                (_b = onCompleteRef.current) === null || _b === void 0 ? void 0 : _b.call(onCompleteRef);
            }
        };
        // Start animation
        timerRef.current = setTimeout(animateNextWord, speed);
        return () => {
            if (timerRef.current) {
                clearTimeout(timerRef.current);
            }
        };
    }, [enabled, isComplete, speed]);
    const reset = () => {
        if (timerRef.current) {
            clearTimeout(timerRef.current);
        }
        currentIndexRef.current = 0;
        setDisplayText('');
        setIsComplete(false);
    };
    return {
        displayText,
        isComplete,
        reset,
    };
};

export { useTypewriter };
