"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const React = require("react");
function useSpeechRecognition(options) {
  const { lang = "zh-CN", continuous = true, interimResults = true } = options || {};
  const onResultRef = React.useRef(options?.onResult);
  const onErrorRef = React.useRef(options?.onError);
  const [isSupported, setIsSupported] = React.useState(false);
  const [isListening, setIsListening] = React.useState(false);
  const [error, setError] = React.useState(null);
  const recognitionRef = React.useRef(null);
  const stoppingRef = React.useRef(false);
  const startingRef = React.useRef(false);
  const processedFinalCountRef = React.useRef(0);
  const lastInterimRef = React.useRef("");
  const finalEmittedRef = React.useRef(false);
  React.useEffect(() => {
    onResultRef.current = options?.onResult;
    onErrorRef.current = options?.onError;
  }, [options?.onResult, options?.onError]);
  React.useEffect(() => {
    const SpeechRecognitionImpl = window.SpeechRecognition || window.webkitSpeechRecognition;
    if (!SpeechRecognitionImpl) {
      setIsSupported(false);
      return;
    }
    setIsSupported(true);
    const recognition = new SpeechRecognitionImpl();
    recognition.lang = lang;
    recognition.continuous = continuous;
    recognition.interimResults = interimResults;
    if (typeof recognition.maxAlternatives === "number") {
      recognition.maxAlternatives = 1;
    }
    recognition.onresult = (event) => {
      let newFinalText = "";
      for (let i = processedFinalCountRef.current; i < event.results.length; i++) {
        const result = event.results[i];
        if (result.isFinal) {
          newFinalText += result[0]?.transcript || "";
          processedFinalCountRef.current = i + 1;
        }
      }
      if (newFinalText) {
        onResultRef.current?.(newFinalText, true);
        finalEmittedRef.current = true;
        lastInterimRef.current = "";
        return;
      }
      let currentInterimText = "";
      for (let i = event.results.length - 1; i >= 0; i--) {
        const result = event.results[i];
        if (!result.isFinal) {
          currentInterimText = result[0]?.transcript || "";
          break;
        }
      }
      if (currentInterimText && currentInterimText !== lastInterimRef.current) {
        onResultRef.current?.(currentInterimText, false);
        lastInterimRef.current = currentInterimText;
      }
    };
    recognition.onerror = (event) => {
      const message = event.error || "unknown-error";
      if (message === "aborted" && stoppingRef.current) {
        stoppingRef.current = false;
        startingRef.current = false;
        return;
      }
      if (message === "no-speech") {
        return;
      }
      setError(message);
      onErrorRef.current?.(message);
      setIsListening(false);
      startingRef.current = false;
    };
    recognition.onstart = () => {
      setIsListening(true);
      startingRef.current = false;
      processedFinalCountRef.current = 0;
      lastInterimRef.current = "";
      finalEmittedRef.current = false;
    };
    recognition.onend = () => {
      setIsListening(false);
      startingRef.current = false;
      stoppingRef.current = false;
      if (!finalEmittedRef.current && lastInterimRef.current) {
        onResultRef.current?.(lastInterimRef.current, true);
      }
    };
    recognitionRef.current = recognition;
    return () => {
      try {
        recognition.stop();
      } catch {
      }
      recognitionRef.current = null;
      processedFinalCountRef.current = 0;
      lastInterimRef.current = "";
      finalEmittedRef.current = false;
    };
  }, [lang, continuous, interimResults]);
  const start = () => {
    if (!recognitionRef.current) return;
    if (isListening || startingRef.current) return;
    setError(null);
    try {
      startingRef.current = true;
      recognitionRef.current.start();
      setIsListening(true);
    } catch (e) {
      const message = e instanceof Error ? e.message : "failed-to-start";
      setError(message);
      onErrorRef.current?.(message);
      startingRef.current = false;
    }
  };
  const stop = () => {
    if (!recognitionRef.current) return;
    if (!isListening && !startingRef.current) return;
    try {
      stoppingRef.current = true;
      recognitionRef.current.stop();
      setIsListening(false);
    } catch (e) {
      const message = e instanceof Error ? e.message : "failed-to-stop";
      setError(message);
      onErrorRef.current?.(message);
      stoppingRef.current = false;
    }
  };
  return {
    isSupported,
    isListening,
    error,
    start,
    stop
  };
}
exports.useSpeechRecognition = useSpeechRecognition;
//# sourceMappingURL=use-speech-recognition.cjs.map
