import React, { useState, useRef, useEffect } from 'react';
import { Button } from '../ui/button';

const FreeTextToSpeech = () => {
  // State management
  const [text, setText] = useState('');
  const [voices, setVoices] = useState([]);
  const [selectedVoice, setSelectedVoice] = useState('');
  const [pitch, setPitch] = useState(1);
  const [rate, setRate] = useState(1);
  const [volume, setVolume] = useState(1);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(null);
  const [status, setStatus] = useState('Enter text to convert to speech');
  const [isSpeaking, setIsSpeaking] = useState(false);
  const [isPaused, setIsPaused] = useState(false);
  const [copied, setCopied] = useState(false);
  const [debugLogs, setDebugLogs] = useState([]);
  const [showDebug, setShowDebug] = useState(false);
  
  // Refs
  const synthRef = useRef(null);
  const utteranceRef = useRef(null);
  const audioRef = useRef(null);
  const textareaRef = useRef(null);

  // Debug logging
  const addDebugLog = (message) => {
    const timestamp = new Date().toISOString().split('T')[1].split('.')[0];
    const logMessage = `${timestamp}: ${message}`;
    setDebugLogs(prev => [...prev.slice(-100), logMessage]);
    console.debug(logMessage);
  };

  // Initialize speech synthesis
  useEffect(() => {
    if (typeof window !== 'undefined') {
      synthRef.current = window.speechSynthesis;
      
      const loadVoices = () => {
        const availableVoices = synthRef.current.getVoices();
        setVoices(availableVoices);
        if (availableVoices.length > 0) {
          setSelectedVoice(availableVoices[0].name);
        }
        addDebugLog(`Loaded ${availableVoices.length} voices`);
      };

      // Chrome loads voices asynchronously
      synthRef.current.onvoiceschanged = loadVoices;
      loadVoices();

      return () => {
        if (synthRef.current) {
          synthRef.current.onvoiceschanged = null;
        }
      };
    }
  }, []);

  // Handle speaking
  const handleSpeak = () => {
    if (!text.trim()) {
      setError('Please enter some text to speak');
      setStatus('Please enter some text to speak');
      addDebugLog('No text provided for speech');
      return;
    }

    if (!synthRef.current) {
      setError('Speech synthesis not supported in this browser');
      setStatus('Speech synthesis not supported');
      addDebugLog('Speech synthesis API not available');
      return;
    }

    if (isPaused) {
      synthRef.current.resume();
      setIsPaused(false);
      setIsSpeaking(true);
      setStatus('Resumed speaking');
      addDebugLog('Resumed speech playback');
      return;
    }

    // Cancel any current speech
    synthRef.current.cancel();

    // Create a new utterance
    const utterance = new SpeechSynthesisUtterance(text);
    utteranceRef.current = utterance;

    // Set utterance properties
    const selectedVoiceObj = voices.find(v => v.name === selectedVoice);
    if (selectedVoiceObj) {
      utterance.voice = selectedVoiceObj;
      addDebugLog(`Using voice: ${selectedVoiceObj.name} (${selectedVoiceObj.lang})`);
    }
    utterance.pitch = pitch;
    utterance.rate = rate;
    utterance.volume = volume;

    // Event handlers
    utterance.onstart = () => {
      setIsSpeaking(true);
      setIsPaused(false);
      setStatus('Speaking...');
      addDebugLog('Speech started');
    };

    utterance.onend = () => {
      setIsSpeaking(false);
      setIsPaused(false);
      setStatus('Finished speaking');
      addDebugLog('Speech completed');
    };

    utterance.onerror = (event) => {
      setIsSpeaking(false);
      setIsPaused(false);
      setStatus(`Error occurred: ${event.error}`);
      addDebugLog(`Speech error: ${event.error}`);
    };

    // Speak the utterance
    synthRef.current.speak(utterance);
    setStatus('Started speaking...');
    addDebugLog('Initiated speech synthesis');
  };

  const handlePause = () => {
    if (isSpeaking && !isPaused && synthRef.current) {
      synthRef.current.pause();
      setIsPaused(true);
      setIsSpeaking(false);
      setStatus('Paused');
      addDebugLog('Speech paused');
    }
  };

  const handleStop = () => {
    if (synthRef.current) {
      synthRef.current.cancel();
      setIsSpeaking(false);
      setIsPaused(false);
      setStatus('Stopped speaking');
      addDebugLog('Speech stopped');
    }
  };

  const handleDownload = () => {
    setStatus('Download requires a TTS API service');
    setError('Download functionality requires a TTS API service');
    addDebugLog('Download attempted (not implemented)');
  };

  // Copy text to clipboard
  const copyToClipboard = () => {
    if (!text) return;
    
    navigator.clipboard.writeText(text).then(() => {
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
      addDebugLog('Text copied to clipboard');
    }).catch(err => {
      const errorMsg = 'Failed to copy text to clipboard';
      addDebugLog(`${errorMsg}: ${err.message}`);
      setError(errorMsg);
    });
  };

  // Clear all inputs and states
  const clearAll = () => {
    setText('');
    setError(null);
    setStatus('Enter text to convert to speech');
    
    if (synthRef.current) {
      synthRef.current.cancel();
    }
    
    setIsSpeaking(false);
    setIsPaused(false);
    
    addDebugLog('All inputs and states cleared');
  };

  // Helper functions
  const clearDebugLogs = () => {
    setDebugLogs([]);
    addDebugLog('Debug logs cleared');
  };

  const toggleDebug = () => {
    setShowDebug(!showDebug);
    addDebugLog(`Debug panel ${showDebug ? 'hidden' : 'shown'}`);
  };

  return (
    <div className="container mx-auto px-4 max-w-4xl my-6">
      <div className="bg-white rounded-lg shadow-md p-6">
        <div className="flex justify-between items-center mb-6">
          <h1 className="text-2xl font-bold text-gray-800">Text to Speech (Using Google)</h1>
          <Button 
            onClick={toggleDebug}
            variant="outline"
            size="sm"
          >
            {showDebug ? 'Hide Debug' : 'Show Debug'}
          </Button>
        </div>

        {/* Text Input Section */}
        <div className="mb-6">
          <div className="flex justify-between items-center mb-2">
            <label htmlFor="tts-text" className="block text-sm font-medium text-gray-700">
              Enter Text
            </label>
            <div className="flex gap-2">
              <Button
                variant="outline"
                size="sm"
                onClick={copyToClipboard}
                disabled={!text || isSpeaking}
              >
                {copied ? 'Copied!' : 'Copy Text'}
              </Button>
              <Button
                variant="outline"
                size="sm"
                onClick={clearAll}
                disabled={isSpeaking}
              >
                Clear All
              </Button>
            </div>
          </div>
          <textarea
            ref={textareaRef}
            id="tts-text"
            rows={6}
            className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-[#6d9e37] focus:border-[#6d9e37] bg-white text-gray-800"
            placeholder="Type or paste your text here..."
            value={text}
            onChange={(e) => setText(e.target.value)}
            disabled={isSpeaking}
          />
        </div>

        {/* Controls */}
        <div className="mb-6 p-4 border border-gray-200 rounded-lg">
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            {/* Voice Selection */}
            <div>
              <label htmlFor="voice-select" className="block text-sm font-medium text-gray-700 mb-1">
                Select Voice
              </label>
              <select
                id="voice-select"
                className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-[#6d9e37] focus:border-[#6d9e37]"
                value={selectedVoice}
                onChange={(e) => setSelectedVoice(e.target.value)}
                disabled={isSpeaking}
              >
                {voices.length > 0 ? (
                  voices.map((voice) => (
                    <option key={voice.name} value={voice.name}>
                      {voice.name} ({voice.lang})
                    </option>
                  ))
                ) : (
                  <option value="">Loading voices...</option>
                )}
              </select>
            </div>

            {/* Pitch Control */}
            <div>
              <label htmlFor="pitch" className="block text-sm font-medium text-gray-700 mb-1">
                Pitch: {pitch.toFixed(1)}
              </label>
              <input
                type="range"
                id="pitch"
                min="0.5"
                max="2"
                step="0.1"
                value={pitch}
                onChange={(e) => setPitch(parseFloat(e.target.value))}
                className="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-[#6d9e37]"
                disabled={isSpeaking}
              />
            </div>

            {/* Rate Control */}
            <div>
              <label htmlFor="rate" className="block text-sm font-medium text-gray-700 mb-1">
                Speed: {rate.toFixed(1)}
              </label>
              <input
                type="range"
                id="rate"
                min="0.5"
                max="2"
                step="0.1"
                value={rate}
                onChange={(e) => setRate(parseFloat(e.target.value))}
                className="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-[#6d9e37]"
                disabled={isSpeaking}
              />
            </div>

            {/* Volume Control */}
            <div>
              <label htmlFor="volume" className="block text-sm font-medium text-gray-700 mb-1">
                Volume: {volume.toFixed(1)}
              </label>
              <input
                type="range"
                id="volume"
                min="0"
                max="1"
                step="0.1"
                value={volume}
                onChange={(e) => setVolume(parseFloat(e.target.value))}
                className="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-[#6d9e37]"
                disabled={isSpeaking}
              />
            </div>
          </div>
        </div>

        {/* Action Buttons */}
        <div className="flex flex-wrap gap-3 mb-6">
          <Button
            onClick={handleSpeak}
            disabled={!text.trim() || (isSpeaking && !isPaused)}
            className="px-6 py-3 text-lg flex-1 min-w-[200px]"
          >
            {isPaused ? 'Resume' : 'Speak'}
          </Button>
          
          <Button
            onClick={handlePause}
            disabled={!isSpeaking || isPaused}
            variant="outline"
            className="px-6 py-3 text-lg flex-1 min-w-[200px]"
          >
            Pause
          </Button>

          <Button
            onClick={handleStop}
            disabled={!isSpeaking && !isPaused}
            variant="outline"
            className="px-6 py-3 text-lg flex-1 min-w-[200px]"
          >
            Stop
          </Button>

          <Button
            onClick={handleDownload}
            variant="outline"
            className="px-6 py-3 text-lg flex-1 min-w-[200px]"
          >
            Download Audio
          </Button>
        </div>

        {/* Status */}
        <div className="mb-6 text-center">
          <p className={`text-sm ${
            error ? 'text-red-600' : 
            isSpeaking ? 'text-[#6d9e37]' : 
            isPaused ? 'text-amber-600' :
            'text-gray-600'
          }`}>
            {status}
          </p>
        </div>

        {/* Error Display */}
        {error && (
          <div className="mt-6 p-4 bg-red-50 border border-red-200 rounded-lg">
            <div className="flex items-center text-red-600">
              <svg className="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
              </svg>
              <h3 className="font-medium">Error</h3>
            </div>
            <p className="mt-2 text-sm text-red-600">{error}</p>
          </div>
        )}

        {/* Debug Section */}
        {showDebug && (
          <div className="mt-8 border rounded-lg overflow-hidden">
            <div className="bg-gray-50 px-4 py-3 border-b flex justify-between items-center">
              <h3 className="font-medium text-gray-700">Debug Logs</h3>
              <div className="flex gap-2">
                <Button 
                  size="sm"
                  variant="outline"
                  onClick={clearDebugLogs}
                  className="text-sm">
                  Clear Logs
                </Button>
                <Button 
                  size="sm"
                  variant="outline"
                  onClick={() => {
                    const blob = new Blob([debugLogs.join('\n')], { type: 'text/plain' });
                    const url = URL.createObjectURL(blob);
                    const a = document.createElement('a');
                    a.href = url;
                    a.download = `tts-debug-${new Date().toISOString()}.log`;
                    a.click();
                    URL.revokeObjectURL(url);
                  }}
                  className="text-sm">
                  Export Logs
                </Button>
              </div>
            </div>
            <div className="p-4 bg-white max-h-60 overflow-y-auto">
              {debugLogs.length > 0 ? (
                <div className="space-y-1">
                  {debugLogs.map((log, index) => (
                    <div key={index} className="text-xs font-mono text-gray-800 border-b border-gray-100 pb-1">
                      {log}
                    </div>
                  ))}
                </div>
              ) : (
                <p className="text-sm text-gray-500">No debug logs yet. Interactions will appear here.</p>
              )}
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

export default FreeTextToSpeech;