import { useState, useEffect } from 'react';
import { api } from '../lib/api';
import { VoicePreviewButton } from './VoicePreviewButton';
import { TTSSettingsPanel } from './TTSSettingsPanel';
import { ElevenLabsSettingsPanel } from './ElevenLabsSettingsPanel';
import type { TTSPreferences, ProviderVoicesResponse, LanguagesResponse, TTSProvider } from '../types/api';

interface VoiceSelectorProps {
  selectedLanguages: string[];
  preferences: TTSPreferences;
  onChange: (preferences: TTSPreferences) => void;
  disabled?: boolean;
}

export function VoiceSelector({
  selectedLanguages,
  preferences,
  onChange,
  disabled
}: VoiceSelectorProps) {
  const [voices, setVoices] = useState<ProviderVoicesResponse | null>(null);
  const [languages, setLanguages] = useState<LanguagesResponse | null>(null);
  const [activeLanguage, setActiveLanguage] = useState<string>(selectedLanguages[0] || 'en');
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  // Fetch voices and languages when provider changes
  useEffect(() => {
    const fetchData = async () => {
      try {
        setIsLoading(true);
        setError(null);
        const [voicesData, languagesData] = await Promise.all([
          api.getVoices(preferences.provider),
          api.getLanguages()
        ]);
        setVoices(voicesData);
        setLanguages(languagesData);

        // Set default voice from API response if switching providers
        if (voicesData.available === false) {
          setError(voicesData.error || 'ElevenLabs TTS is not configured on the server. Contact your administrator to set up the ELEVENLABS_API_KEY.');
        } else if (voicesData.default && voicesData.voices.length > 0) {
          // Only reset default voice if the current one isn't in the new voice list
          const currentVoiceExists = voicesData.voices.some(v => v.id === preferences.default_voice);
          if (!currentVoiceExists) {
            onChange({
              ...preferences,
              default_voice: voicesData.default,
              voices_per_language: {},
            });
          }
        }
      } catch (err) {
        setError('Failed to load voice options');
        console.error('Voice selector error:', err);
      } finally {
        setIsLoading(false);
      }
    };

    fetchData();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [preferences.provider]);

  // Update active language when selected languages change
  useEffect(() => {
    if (selectedLanguages.length > 0 && !selectedLanguages.includes(activeLanguage)) {
      setActiveLanguage(selectedLanguages[0]);
    }
  }, [selectedLanguages, activeLanguage]);

  const handleProviderChange = (provider: TTSProvider) => {
    if (provider === preferences.provider) return;
    onChange({
      ...preferences,
      provider,
      default_voice: '', // Will be set after fetch
      voices_per_language: {},
    });
  };

  const handleDefaultVoiceChange = (voiceId: string) => {
    onChange({
      ...preferences,
      default_voice: voiceId
    });
  };

  const handleLanguageVoiceChange = (language: string, voiceId: string) => {
    const newVoicesPerLanguage = {
      ...preferences.voices_per_language,
      [language]: voiceId
    };

    // If voice matches default, remove from per-language overrides
    if (voiceId === preferences.default_voice) {
      delete newVoicesPerLanguage[language];
    }

    onChange({
      ...preferences,
      voices_per_language: newVoicesPerLanguage
    });
  };

  const getVoiceForLanguage = (language: string): string => {
    return preferences.voices_per_language[language] || preferences.default_voice;
  };

  if (isLoading) {
    return (
      <div className="flex items-center gap-2 text-gray-500">
        <svg className="animate-spin h-5 w-5" viewBox="0 0 24 24">
          <circle
            className="opacity-25"
            cx="12"
            cy="12"
            r="10"
            stroke="currentColor"
            strokeWidth="4"
            fill="none"
          />
          <path
            className="opacity-75"
            fill="currentColor"
            d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
          />
        </svg>
        Loading voice options...
      </div>
    );
  }

  if (error || !voices || !languages) {
    return (
      <div className="text-red-600 text-sm">
        {error || 'Failed to load voice options'}
      </div>
    );
  }

  // Filter languages to only show selected ones
  const displayLanguages = selectedLanguages.length > 0
    ? selectedLanguages
    : ['en'];

  return (
    <div className="space-y-4">
      {/* Provider Toggle */}
      <div className="bg-gray-50 rounded-lg p-4">
        <label className="block text-sm font-medium text-gray-700 mb-2">
          TTS Provider
        </label>
        <div className="flex rounded-lg border border-gray-300 overflow-hidden">
          <button
            type="button"
            onClick={() => handleProviderChange('gemini')}
            disabled={disabled}
            className={`flex-1 px-4 py-2 text-sm font-medium transition-colors ${
              preferences.provider === 'gemini'
                ? 'bg-blue-600 text-white'
                : 'bg-white text-gray-700 hover:bg-gray-50'
            } disabled:opacity-50`}
          >
            Gemini
          </button>
          <button
            type="button"
            onClick={() => handleProviderChange('elevenlabs')}
            disabled={disabled}
            className={`flex-1 px-4 py-2 text-sm font-medium border-l border-gray-300 transition-colors ${
              preferences.provider === 'elevenlabs'
                ? 'bg-blue-600 text-white'
                : 'bg-white text-gray-700 hover:bg-gray-50'
            } disabled:opacity-50`}
          >
            ElevenLabs
          </button>
        </div>
      </div>

      {/* Default Voice Selection */}
      <div className="bg-gray-50 rounded-lg p-4">
        <label className="block text-sm font-medium text-gray-700 mb-2">
          Default Voice
        </label>
        <p className="text-xs text-gray-500 mb-3">
          This voice will be used for all languages unless overridden below.
        </p>
        <div className="flex items-center gap-3">
          <select
            value={preferences.default_voice}
            onChange={(e) => handleDefaultVoiceChange(e.target.value)}
            disabled={disabled}
            className="flex-1 rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 text-sm"
          >
            {voices.voices.map((voice) => (
              <option key={voice.id} value={voice.id}>
                {voice.name}
                {voice.category ? ` (${voice.category})` : ''}
              </option>
            ))}
          </select>
          <VoicePreviewButton
            voiceName={preferences.default_voice}
            language={displayLanguages[0] || 'en'}
            disabled={disabled}
            provider={preferences.provider}
            model={preferences.model}
            speed={preferences.speed}
            stylePreset={preferences.style_preset}
            customStylePrompt={preferences.custom_style_prompt}
            stability={preferences.stability}
            similarityBoost={preferences.similarity_boost}
          />
        </div>
      </div>

      {/* TTS Settings - Provider-specific */}
      {preferences.provider === 'elevenlabs' ? (
        <ElevenLabsSettingsPanel
          preferences={preferences}
          onChange={onChange}
          disabled={disabled}
        />
      ) : (
        <TTSSettingsPanel
          preferences={preferences}
          onChange={onChange}
          disabled={disabled}
        />
      )}

      {/* Per-Language Voice Overrides */}
      {displayLanguages.length > 1 && (
        <div className="bg-gray-50 rounded-lg p-4">
          <label className="block text-sm font-medium text-gray-700 mb-2">
            Per-Language Voice Settings
          </label>
          <p className="text-xs text-gray-500 mb-3">
            Optionally choose different voices for specific languages.
          </p>

          {/* Language Tabs */}
          <div className="flex flex-wrap gap-1 mb-4 border-b border-gray-200">
            {displayLanguages.map((lang) => (
              <button
                key={lang}
                type="button"
                onClick={() => setActiveLanguage(lang)}
                className={`
                  px-3 py-2 text-sm font-medium rounded-t-md transition-colors
                  ${activeLanguage === lang
                    ? 'bg-white text-blue-600 border-b-2 border-blue-600 -mb-px'
                    : 'text-gray-500 hover:text-gray-700 hover:bg-gray-100'
                  }
                `}
              >
                {languages.languages[lang] || lang.toUpperCase()}
                {preferences.voices_per_language[lang] && (
                  <span className="ml-1 text-xs text-blue-500">*</span>
                )}
              </button>
            ))}
          </div>

          {/* Voice Selection for Active Language */}
          <div className="flex items-center gap-3">
            <select
              value={getVoiceForLanguage(activeLanguage)}
              onChange={(e) => handleLanguageVoiceChange(activeLanguage, e.target.value)}
              disabled={disabled}
              className="flex-1 rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 text-sm"
            >
              {voices.voices.map((voice) => (
                <option key={voice.id} value={voice.id}>
                  {voice.name}
                  {voice.category ? ` (${voice.category})` : ''}
                  {voice.id === preferences.default_voice ? ' (default)' : ''}
                </option>
              ))}
            </select>
            <VoicePreviewButton
              voiceName={getVoiceForLanguage(activeLanguage)}
              language={activeLanguage}
              disabled={disabled}
              provider={preferences.provider}
              model={preferences.model}
              speed={preferences.speed}
              stylePreset={preferences.style_preset}
              customStylePrompt={preferences.custom_style_prompt}
              stability={preferences.stability}
              similarityBoost={preferences.similarity_boost}
            />
          </div>

          {/* Sample Text Display */}
          <div className="mt-3 p-3 bg-white rounded border border-gray-200">
            <span className="text-xs text-gray-500 block mb-1">Preview text:</span>
            <span className="text-sm text-gray-700 italic">
              "{languages.preview_samples[activeLanguage] || languages.preview_samples['en']}"
            </span>
          </div>
        </div>
      )}
    </div>
  );
}
