
import React, { useState, useRef } from 'react';
import { VoiceName } from '../types';
import { AVAILABLE_VOICES } from '../constants';
import { Play, Pause, Loader2, Check, Volume2 } from 'lucide-react';
import { generateSpeechFromText } from '../services/geminiService';
import { base64ToUint8Array, createWavBlob } from '../services/audioUtils';

interface VoiceSelectorProps {
  selectedVoice: VoiceName;
  onVoiceChange: (voice: VoiceName) => void;
}

// Compact selector for header
export const VoiceSelectorCompact: React.FC<VoiceSelectorProps> = ({ selectedVoice, onVoiceChange }) => {
  const currentVoice = AVAILABLE_VOICES.find(v => v.name === selectedVoice);

  return (
    <div className="flex items-center gap-2">
      <span className="text-lg">{currentVoice?.emoji}</span>
      <select
        value={selectedVoice}
        onChange={(e) => onVoiceChange(e.target.value as VoiceName)}
        className="bg-transparent border-none text-sm font-medium text-slate-700 dark:text-slate-200 cursor-pointer focus:outline-none"
      >
        {AVAILABLE_VOICES.map((v) => (
          <option key={v.name} value={v.name}>
            {v.label}
          </option>
        ))}
      </select>
    </div>
  );
};

// Full voice panel with cards and preview
export const VoicePanel: React.FC<VoiceSelectorProps> = ({ selectedVoice, onVoiceChange }) => {
  const [previewingVoice, setPreviewingVoice] = useState<VoiceName | null>(null);
  const [loadingPreview, setLoadingPreview] = useState<VoiceName | null>(null);
  const audioRef = useRef<HTMLAudioElement | null>(null);

  const handlePreview = async (voice: typeof AVAILABLE_VOICES[0]) => {
    // If already previewing this voice, stop it
    if (previewingVoice === voice.name) {
      if (audioRef.current) {
        audioRef.current.pause();
        audioRef.current.src = '';
      }
      setPreviewingVoice(null);
      return;
    }

    // Stop any current preview
    if (audioRef.current) {
      audioRef.current.pause();
      audioRef.current.src = '';
    }

    setLoadingPreview(voice.name);
    setPreviewingVoice(null);

    try {
      const base64Audio = await generateSpeechFromText(voice.previewText, voice.name);
      const pcmData = base64ToUint8Array(base64Audio);
      const wavBlob = createWavBlob(pcmData);
      const audioUrl = URL.createObjectURL(wavBlob);

      if (!audioRef.current) {
        audioRef.current = new Audio();
      }

      audioRef.current.src = audioUrl;
      audioRef.current.onended = () => {
        setPreviewingVoice(null);
        URL.revokeObjectURL(audioUrl);
      };
      audioRef.current.onerror = () => {
        setPreviewingVoice(null);
        URL.revokeObjectURL(audioUrl);
      };

      await audioRef.current.play();
      setPreviewingVoice(voice.name);
    } catch (error) {
      console.error('Preview failed:', error);
    } finally {
      setLoadingPreview(null);
    }
  };

  const handleSelect = (voiceName: VoiceName) => {
    onVoiceChange(voiceName);
  };

  return (
    <div className="space-y-3">
      <div className="flex items-center gap-2 px-1">
        <Volume2 className="w-4 h-4 text-blue-500" />
        <h3 className="text-sm font-semibold text-slate-700 dark:text-slate-300">Choose Your Voice</h3>
      </div>

      <div className="grid grid-cols-2 sm:grid-cols-3 gap-3">
        {AVAILABLE_VOICES.map((voice) => {
          const isSelected = selectedVoice === voice.name;
          const isPreviewing = previewingVoice === voice.name;
          const isLoading = loadingPreview === voice.name;

          return (
            <div
              key={voice.name}
              className={`
                relative p-4 rounded-2xl border-2 transition-all cursor-pointer
                ${isSelected
                  ? 'border-blue-500 bg-blue-50 dark:bg-blue-900/30 shadow-md'
                  : 'border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900 hover:border-slate-300 dark:hover:border-slate-600 hover:shadow-sm'
                }
              `}
              onClick={() => handleSelect(voice.name)}
            >
              {/* Selected checkmark */}
              {isSelected && (
                <div className="absolute top-2 right-2 w-5 h-5 bg-blue-500 rounded-full flex items-center justify-center">
                  <Check className="w-3 h-3 text-white" />
                </div>
              )}

              {/* Voice info */}
              <div className="text-center space-y-2">
                <div className="text-2xl">{voice.emoji}</div>
                <div>
                  <p className={`font-semibold ${isSelected ? 'text-blue-700 dark:text-blue-300' : 'text-slate-800 dark:text-slate-200'}`}>
                    {voice.label}
                  </p>
                  <p className="text-xs text-slate-500 dark:text-slate-400 mt-0.5">
                    {voice.description}
                  </p>
                </div>

                {/* Preview button */}
                <button
                  onClick={(e) => {
                    e.stopPropagation();
                    handlePreview(voice);
                  }}
                  disabled={isLoading}
                  className={`
                    w-full mt-2 py-2 px-3 rounded-xl text-xs font-medium transition-all flex items-center justify-center gap-2
                    ${isPreviewing
                      ? 'bg-blue-500 text-white'
                      : isSelected
                        ? 'bg-blue-100 text-blue-700 hover:bg-blue-200 dark:bg-blue-800/50 dark:text-blue-200 dark:hover:bg-blue-800'
                        : 'bg-slate-100 text-slate-600 hover:bg-slate-200 dark:bg-slate-800 dark:text-slate-300 dark:hover:bg-slate-700'
                    }
                    ${isLoading ? 'opacity-70 cursor-wait' : ''}
                  `}
                >
                  {isLoading ? (
                    <>
                      <Loader2 className="w-3 h-3 animate-spin" />
                      Loading...
                    </>
                  ) : isPreviewing ? (
                    <>
                      <Pause className="w-3 h-3" />
                      Stop
                    </>
                  ) : (
                    <>
                      <Play className="w-3 h-3" />
                      Preview
                    </>
                  )}
                </button>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
};

// Keep backward compatibility
export const VoiceSelector = VoiceSelectorCompact;
