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

export function usePushToTalk() {
  const [isRecording, setIsRecording] = useState(false);
  const streamRef      = useRef(null);   // mic stream, acquired on demand
  const recorderRef    = useRef(null);
  const recognitionRef = useRef(null);
  const chunksRef      = useRef([]);
  const transcriptRef  = useRef('');

  // Resolves once the mic stream is acquired and MediaRecorder is running.
  // Throws if mic permission is denied.
  const start = useCallback(async () => {
    if (isRecording) return;
    chunksRef.current     = [];
    transcriptRef.current = '';

    // ── Acquire mic stream (on-demand, not pre-warmed) ───────────
    // If the previous stream is still active (same session, held open) reuse it;
    // otherwise request a new one — this is where the brief "preparing" delay happens.
    if (!streamRef.current?.active) {
      streamRef.current = await navigator.mediaDevices.getUserMedia({ audio: true });
    }

    // ── MediaRecorder ────────────────────────────────────────────
    const mimeType = MediaRecorder.isTypeSupported('audio/webm;codecs=opus')
      ? 'audio/webm;codecs=opus' : 'audio/webm';
    const recorder = new MediaRecorder(streamRef.current, { mimeType });
    recorder.ondataavailable = (e) => { if (e.data.size > 0) chunksRef.current.push(e.data); };
    recorder.start(100);
    recorderRef.current = recorder;

    // ── SpeechRecognition: real-time transcript ──────────────────
    const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
    if (SR) {
      const sr = new SR();
      sr.lang = 'zh-CN';
      sr.interimResults = true;
      sr.continuous = true;
      sr.onresult = (e) => {
        let final = '';
        for (const res of e.results) {
          if (res.isFinal) final += res[0].transcript;
        }
        if (final) transcriptRef.current = final;
      };
      sr.onerror = (e) => { console.warn('SpeechRecognition error:', e.error); };
      sr.start();
      recognitionRef.current = sr;
    }

    setIsRecording(true);
    // start() resolves here — caller knows mic is live and recording has begun
  }, [isRecording]);

  // Returns { transcript, audioBase64, mimeType }
  const stop = useCallback(() => new Promise((resolve) => {
    setIsRecording(false);

    const transcript = transcriptRef.current;

    try { recognitionRef.current?.stop(); } catch {}
    recognitionRef.current = null;

    // Release mic stream so the OS indicator light turns off
    streamRef.current?.getTracks().forEach(t => t.stop());
    streamRef.current = null;

    const recorder = recorderRef.current;
    if (!recorder) {
      return resolve({ transcript, audioBase64: null, mimeType: null });
    }

    recorder.onstop = async () => {
      const mimeType = recorder.mimeType;

      if (chunksRef.current.length === 0) {
        return resolve({ transcript, audioBase64: null, mimeType });
      }

      const blob   = new Blob(chunksRef.current, { type: mimeType });
      const reader = new FileReader();
      reader.onloadend = () => {
        resolve({ transcript, audioBase64: reader.result.split(',')[1], mimeType });
      };
      reader.readAsDataURL(blob);
    };
    recorder.stop();
    recorderRef.current = null;
  }), []);

  return { isRecording, start, stop };
}

