import { useState, useEffect } from 'react';
import { api } from '../lib/api';
import { VoicePreviewButton } from './VoicePreviewButton';
import { TTSSettingsPanel } from './TTSSettingsPanel';
import type { TTSPreferences, VoicesResponse, LanguagesResponse } 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<VoicesResponse | 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 on mount
  useEffect(() => {
    const fetchData = async () => {
      try {
        setIsLoading(true);
        const [voicesData, languagesData] = await Promise.all([
          api.getVoices(),
          api.getLanguages()
        ]);
        setVoices(voicesData);
        setLanguages(languagesData);
      } catch (err) {
        setError('Failed to load voice options');
        console.error('Voice selector error:', err);
      } finally {
        setIsLoading(false);
      }
    };

    fetchData();
  }, []);

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

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

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

    // If voice matches default, remove from per-language overrides
    if (voice === 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
  // The first language in selectedLanguages is the primary/source language
  const displayLanguages = selectedLanguages.length > 0
    ? selectedLanguages
    : ['en'];

  return (
    <div className="space-y-4">
      {/* 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} value={voice}>
                {voice}
              </option>
            ))}
          </select>
          <VoicePreviewButton
            voiceName={preferences.default_voice}
            language={displayLanguages[0] || 'en'}
            disabled={disabled}
            model={preferences.model}
            speed={preferences.speed}
            stylePreset={preferences.style_preset}
            customStylePrompt={preferences.custom_style_prompt}
          />
        </div>
      </div>

      {/* TTS Settings (Model, Speed, Style) */}
      <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} value={voice}>
                  {voice}
                  {voice === preferences.default_voice ? ' (default)' : ''}
                </option>
              ))}
            </select>
            <VoicePreviewButton
              voiceName={getVoiceForLanguage(activeLanguage)}
              language={activeLanguage}
              disabled={disabled}
              model={preferences.model}
              speed={preferences.speed}
              stylePreset={preferences.style_preset}
              customStylePrompt={preferences.custom_style_prompt}
            />
          </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>
  );
}
