"use client";

import { ReactNode, useState } from "react";

type RecognitionInstance = {
  continuous: boolean;
  interimResults: boolean;
  lang: string;
  onresult: ((event: any) => void) | null;
  onerror: ((event: any) => void) | null;
  onend: (() => void) | null;
  start: () => void;
  stop: () => void;
};

type RecognitionConstructor = new () => RecognitionInstance;

declare global {
  interface Window {
    SpeechRecognition?: RecognitionConstructor;
    webkitSpeechRecognition?: RecognitionConstructor;
  }
}

type VoiceInputProps = {
  onTranscript: (text: string) => void;
  disabled?: boolean;
  className?: string;
  idleLabel?: string;
  listeningLabel?: string;
  title?: string;
  children?: ReactNode;
  listeningContent?: ReactNode;
};

export function VoiceInput({
  onTranscript,
  disabled = false,
  className,
  idleLabel = "Voice",
  listeningLabel = "Listening...",
  title,
  children,
  listeningContent
}: VoiceInputProps) {
  const [isListening, setIsListening] = useState(false);

  const toggleListen = () => {
    const Constructor = window.SpeechRecognition ?? window.webkitSpeechRecognition;
    if (!Constructor) {
      alert("Speech recognition is not supported in this browser.");
      return;
    }

    const recognition = new Constructor();
    recognition.lang = "en-US";
    recognition.continuous = false;
    recognition.interimResults = false;

    recognition.onresult = (event) => {
      const transcript = event?.results?.[0]?.[0]?.transcript;
      if (typeof transcript === "string" && transcript.trim()) {
        onTranscript(transcript.trim());
      }
    };

    recognition.onerror = () => {
      setIsListening(false);
    };

    recognition.onend = () => {
      setIsListening(false);
    };

    setIsListening(true);
    recognition.start();
  };

  return (
    <button
      type="button"
      onClick={toggleListen}
      disabled={disabled || isListening}
      className={className}
      title={title}
    >
      {isListening
        ? (listeningContent ?? listeningLabel)
        : (children ?? idleLabel)}
    </button>
  );
}
