import { useCallback, useEffect, useRef, useState } from "react";
import { localStorageService } from "../../services/localStorageService";
const VOICE_DISABLED_KEY = "agents-panel-voice-disabled";
export function useAgentVoiceInput(input) {
    const { inputPlaceholder, language, prompt, textareaRef, setInputPlaceholder, setPrompt, } = input;
    const [isVoiceSupported, setIsVoiceSupported] = useState(false);
    const [isVoiceDisabled, setIsVoiceDisabled] = useState(false);
    const [isListening, setIsListening] = useState(false);
    const recognitionRef = useRef(null);
    const prevPlaceholderRef = useRef(null);
    const promptBeforeVoiceRef = useRef("");
    const voicePressStartRef = useRef(null);
    const voiceHoldTimerRef = useRef(null);
    const voiceHoldModeRef = useRef(false);
    const voicePointerIdRef = useRef(null);
    const voiceStartedOnPressRef = useRef(false);
    useEffect(() => {
        try {
            if (typeof window === "undefined")
                return;
            const SR = window.SpeechRecognition ||
                window.webkitSpeechRecognition;
            setIsVoiceSupported(!!SR);
            if (SR === undefined) {
                setIsVoiceDisabled(true);
                localStorageService.setString(VOICE_DISABLED_KEY, "true");
                return;
            }
            const wasDisabled = localStorageService.getString(VOICE_DISABLED_KEY) === "true";
            setIsVoiceDisabled(wasDisabled);
        }
        catch {
            setIsVoiceSupported(false);
        }
    }, []);
    const startVoice = useCallback(() => {
        try {
            if (isListening)
                return;
            if (typeof window === "undefined")
                return;
            const SR = window.SpeechRecognition ||
                window.webkitSpeechRecognition;
            if (!SR) {
                return;
            }
            const recognition = new SR();
            recognition.lang = language || "en-US";
            recognition.continuous = true;
            recognition.interimResults = true;
            promptBeforeVoiceRef.current = prompt;
            recognition.onstart = () => {
                setIsListening(true);
                prevPlaceholderRef.current = inputPlaceholder;
                setInputPlaceholder("Listening...");
            };
            recognition.onresult = (event) => {
                let lastFinalTranscript = "";
                let interimText = "";
                for (let i = event.results.length - 1; i >= 0; i--) {
                    const result = event.results[i];
                    if (result.isFinal &&
                        !lastFinalTranscript &&
                        (result[0]?.transcript || "").trim()) {
                        lastFinalTranscript = result[0].transcript;
                    }
                    if (!result.isFinal) {
                        interimText = (result[0]?.transcript || "") + interimText;
                    }
                }
                if (interimText) {
                    setInputPlaceholder(`Listening... ${interimText.trim()}`);
                }
                else {
                    setInputPlaceholder("Listening...");
                }
                const base = promptBeforeVoiceRef.current;
                const separator = base && !base.endsWith(" ") ? " " : "";
                const recognized = lastFinalTranscript.trim();
                if (recognized) {
                    setPrompt(base + separator + recognized + " ");
                    if (textareaRef.current) {
                        try {
                            const value = textareaRef.current.value || "";
                            textareaRef.current.selectionStart = value.length;
                            textareaRef.current.selectionEnd = value.length;
                        }
                        catch { }
                    }
                }
            };
            recognition.onerror = (error) => {
                console.warn("Speech recognition error", error);
                if (error?.error === "network") {
                    try {
                        localStorageService.setString(VOICE_DISABLED_KEY, "true");
                        setIsVoiceDisabled(true);
                    }
                    catch { }
                }
            };
            recognition.onend = () => {
                setIsListening(false);
                if (prevPlaceholderRef.current !== null) {
                    setInputPlaceholder(prevPlaceholderRef.current);
                    prevPlaceholderRef.current = null;
                }
                recognitionRef.current = null;
            };
            recognitionRef.current = recognition;
            recognition.start();
        }
        catch (error) {
            console.error("Failed to start voice input", error);
        }
    }, [
        inputPlaceholder,
        isListening,
        language,
        prompt,
        setInputPlaceholder,
        setPrompt,
        textareaRef,
    ]);
    const stopVoice = useCallback(() => {
        try {
            const recognition = recognitionRef.current;
            if (recognition)
                recognition.stop();
        }
        catch { }
    }, []);
    const handleVoicePointerDown = useCallback((event) => {
        event.preventDefault();
        event.stopPropagation();
        if (voicePointerIdRef.current !== null)
            return;
        voicePointerIdRef.current = event.pointerId;
        event.currentTarget.setPointerCapture(event.pointerId);
        voicePressStartRef.current = Date.now();
        voiceHoldModeRef.current = false;
        voiceStartedOnPressRef.current = false;
        if (voiceHoldTimerRef.current) {
            clearTimeout(voiceHoldTimerRef.current);
        }
        if (isListening) {
            return;
        }
        voiceStartedOnPressRef.current = true;
        startVoice();
        voiceHoldTimerRef.current = setTimeout(() => {
            voiceHoldModeRef.current = true;
        }, 1000);
    }, [isListening, startVoice]);
    const handleVoicePointerUp = useCallback((event) => {
        if (voicePointerIdRef.current !== event.pointerId)
            return;
        event.preventDefault();
        event.stopPropagation();
        try {
            event.currentTarget.releasePointerCapture(event.pointerId);
        }
        catch { }
        const pressStart = voicePressStartRef.current;
        const wasHoldMode = voiceHoldModeRef.current;
        const startedOnThisPress = voiceStartedOnPressRef.current;
        if (voiceHoldTimerRef.current) {
            clearTimeout(voiceHoldTimerRef.current);
            voiceHoldTimerRef.current = null;
        }
        voicePressStartRef.current = null;
        voiceHoldModeRef.current = false;
        voicePointerIdRef.current = null;
        voiceStartedOnPressRef.current = false;
        if (wasHoldMode && isListening) {
            stopVoice();
            return;
        }
        if (pressStart && Date.now() - pressStart < 1000) {
            if (startedOnThisPress) {
                return;
            }
            if (isListening) {
                stopVoice();
            }
        }
    }, [isListening, stopVoice]);
    const handleVoicePointerCancel = useCallback((event) => {
        if (voicePointerIdRef.current !== event.pointerId)
            return;
        if (voiceHoldTimerRef.current) {
            clearTimeout(voiceHoldTimerRef.current);
            voiceHoldTimerRef.current = null;
        }
        const wasHoldMode = voiceHoldModeRef.current;
        voicePressStartRef.current = null;
        voiceHoldModeRef.current = false;
        voicePointerIdRef.current = null;
        if (wasHoldMode && isListening) {
            stopVoice();
        }
    }, [isListening, stopVoice]);
    useEffect(() => {
        return () => {
            try {
                const recognition = recognitionRef.current;
                if (recognition) {
                    recognition.onresult = null;
                    recognition.onerror = null;
                    recognition.onend = null;
                    recognition.stop();
                }
            }
            catch { }
            recognitionRef.current = null;
            if (voiceHoldTimerRef.current) {
                clearTimeout(voiceHoldTimerRef.current);
                voiceHoldTimerRef.current = null;
            }
        };
    }, []);
    return {
        isVoiceSupported,
        isVoiceDisabled,
        isListening,
        handleVoicePointerDown,
        handleVoicePointerUp,
        handleVoicePointerCancel,
    };
}
//# sourceMappingURL=useAgentVoiceInput.js.map