'use client';

import { useState, useCallback, useRef, type MouseEvent } from 'react';
import { fileToBase64 } from '@/lib/copilot';

interface VoiceInputProps {
  onVoice: (audioBase64: string, mimeType: string) => void;
  disabled?: boolean;
}

declare global {
  interface Window {
    SpeechRecognition?: new () => SpeechRecognitionLike;
    webkitSpeechRecognition?: new () => SpeechRecognitionLike;
  }
}

interface SpeechRecognitionLike {
  start: () => void;
  stop: () => void;
  onresult: ((event: SpeechRecognitionEventLike) => void) | null;
  onerror: (() => void) | null;
  onend: (() => void) | null;
}

interface SpeechRecognitionEventLike {
  results: { length: number; [key: number]: { 0: { transcript: string } } };
}

export function VoiceInput({ onVoice, disabled }: VoiceInputProps) {
  const [recording, setRecording] = useState(false);
  const [supported, setSupported] = useState(true);
  const mediaRecorderRef = useRef<MediaRecorder | null>(null);
  const chunksRef = useRef<Blob[]>([]);

  const handleStartRecording = useCallback(async () => {
    if (disabled) return;
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
      const recorder = new MediaRecorder(stream);
      chunksRef.current = [];
      recorder.ondataavailable = (e) => {
        if (e.data.size > 0) chunksRef.current.push(e.data);
      };
      recorder.onstop = async () => {
        const blob = new Blob(chunksRef.current, { type: 'audio/webm' });
        const base64 = await fileToBase64(blob);
        onVoice(base64, 'audio/webm');
        stream.getTracks().forEach((track) => track.stop());
      };
      recorder.start();
      mediaRecorderRef.current = recorder;
      setRecording(true);
    } catch {
      setSupported(false);
    }
  }, [disabled, onVoice]);

  const handleStopRecording = useCallback(() => {
    if (mediaRecorderRef.current && recording) {
      mediaRecorderRef.current.stop();
      setRecording(false);
    }
  }, [recording]);

  const handleToggle = useCallback(
    (e: MouseEvent<HTMLButtonElement>) => {
      e.preventDefault();
      if (recording) handleStopRecording();
      else handleStartRecording();
    },
    [recording, handleStartRecording, handleStopRecording]
  );

  if (!supported) {
    return (
      <button disabled className="bg-gray-300 text-gray-500 px-3 py-2 rounded-lg cursor-not-allowed" data-testid="voice-button">
        🎤
      </button>
    );
  }

  return (
    <button
      onClick={handleToggle}
      disabled={disabled}
      className={`${recording ? 'bg-red-600 animate-pulse' : 'bg-gray-200 hover:bg-gray-300'} text-gray-800 px-3 py-2 rounded-lg disabled:opacity-50 disabled:cursor-not-allowed`}
      title={recording ? 'Aufnahme stoppen' : 'Sprachnachricht aufnehmen'}
      data-testid="voice-button"
    >
      🎤
    </button>
  );
}
