/**
 * WorkspaceSettings -- Voice preferences per language.
 *
 * Allows the user to configure a preferred voice for each TTS language.
 * Language detection is automatic; this page lets users override the
 * default Google Cloud voice for specific languages.
 */

import React, { useState, useEffect, useCallback } from 'react';
import { useApiRequest } from '../../../hooks/useApi';
import styles from './WorkspaceSettings.module.css';

interface VoiceMapEntry {
  language: string;
  voiceName: string;
}

interface WorkspaceSettingsProps {
  instanceId: string;
}

export const WorkspaceSettings: React.FC<WorkspaceSettingsProps> = ({ instanceId }) => {
  const { request } = useApiRequest();

  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [testing, setTesting] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState<string | null>(null);

  const [languages, setLanguages] = useState<any[]>([]);
  const [voiceMap, setVoiceMap] = useState<VoiceMapEntry[]>([]);

  const [addLanguage, setAddLanguage] = useState('de-DE');
  const [addVoices, setAddVoices] = useState<any[]>([]);
  const [addVoiceName, setAddVoiceName] = useState('');
  const [loadingVoices, setLoadingVoices] = useState(false);

  const _loadSettings = useCallback(async () => {
    if (!instanceId) return;
    setLoading(true);
    try {
      const [settingsData, languagesData] = await Promise.all([
        request({ url: `/api/workspace/${instanceId}/settings/voice`, method: 'get' }),
        request({ url: `/api/workspace/${instanceId}/voice/languages`, method: 'get' }),
      ]);

      const langList = (languagesData as any)?.languages || [];
      setLanguages(langList);

      const map: Record<string, any> = (settingsData as any)?.ttsVoiceMap || {};
      const entries: VoiceMapEntry[] = Object.entries(map).map(([lang, cfg]) => ({
        language: lang,
        voiceName: typeof cfg === 'string' ? cfg : (cfg as any)?.voiceName || '',
      }));
      setVoiceMap(entries);
    } catch (err: any) {
      setError(err.message || 'Fehler beim Laden der Einstellungen');
    } finally {
      setLoading(false);
    }
  }, [request, instanceId]);

  useEffect(() => { _loadSettings(); }, [_loadSettings]);

  const _loadVoicesForLanguage = useCallback(async (lang: string) => {
    if (!instanceId) return;
    setLoadingVoices(true);
    try {
      const result = await request({
        url: `/api/workspace/${instanceId}/voice/voices`,
        method: 'get',
        params: { language: lang },
      });
      setAddVoices((result as any)?.voices || []);
      setAddVoiceName('');
    } catch {
      setAddVoices([]);
    } finally {
      setLoadingVoices(false);
    }
  }, [request, instanceId]);

  useEffect(() => { _loadVoicesForLanguage(addLanguage); }, [addLanguage, _loadVoicesForLanguage]);

  const _handleAddEntry = useCallback(() => {
    if (!addLanguage) return;
    const exists = voiceMap.some(e => e.language === addLanguage);
    if (exists) {
      setVoiceMap(prev => prev.map(e =>
        e.language === addLanguage ? { ...e, voiceName: addVoiceName } : e
      ));
    } else {
      setVoiceMap(prev => [...prev, { language: addLanguage, voiceName: addVoiceName }]);
    }
    setAddVoiceName('');
  }, [addLanguage, addVoiceName, voiceMap]);

  const _handleRemoveEntry = useCallback((lang: string) => {
    setVoiceMap(prev => prev.filter(e => e.language !== lang));
  }, []);

  const _handleSave = useCallback(async () => {
    if (!instanceId) return;
    setSaving(true);
    setError(null);
    setSuccess(null);
    try {
      const mapObj: Record<string, any> = {};
      voiceMap.forEach(e => {
        mapObj[e.language] = { voiceName: e.voiceName || '' };
      });
      const putResult = await request({
        url: `/api/workspace/${instanceId}/settings/voice`,
        method: 'put',
        data: { ttsVoiceMap: mapObj },
      });
      if ((putResult as any)?.error) {
        setError((putResult as any).error);
        return;
      }
      setSuccess('Einstellungen gespeichert');
      setTimeout(() => setSuccess(null), 3000);
      await _loadSettings();
    } catch (err: any) {
      setError(err.message || 'Fehler beim Speichern');
    } finally {
      setSaving(false);
    }
  }, [request, instanceId, voiceMap]);

  const _handleTestVoice = useCallback(async (lang: string, voice: string) => {
    if (!instanceId) return;
    setTesting(lang);
    try {
      const result: any = await request({
        url: `/api/workspace/${instanceId}/voice/test`,
        method: 'post',
        data: { language: lang, voiceId: voice || undefined, text: `Hallo, das ist ein Stimmtest in ${lang}.` },
      });
      if (result?.success && result?.audio) {
        const audio = new Audio(`data:audio/mp3;base64,${result.audio}`);
        audio.play();
      }
    } catch {
      setError('Stimmtest fehlgeschlagen');
    } finally {
      setTesting(null);
    }
  }, [request, instanceId]);

  const _getLanguageName = useCallback((code: string) => {
    const found = languages.find((l: any) => (l.code || l) === code);
    return found?.name || found?.code || code;
  }, [languages]);

  if (loading) {
    return <div className={styles.loading}>Einstellungen werden geladen...</div>;
  }

  const _defaultLangs = [
    { code: 'de-DE', name: 'Deutsch' },
    { code: 'en-US', name: 'English (US)' },
    { code: 'fr-FR', name: 'Francais' },
    { code: 'it-IT', name: 'Italiano' },
    { code: 'es-ES', name: 'Espanol' },
  ];
  const _displayLanguages = languages.length > 0 ? languages : _defaultLangs;

  return (
    <div className={styles.settings}>
      <h2 className={styles.heading}>Stimmeneinstellungen</h2>

      {error && <div className={styles.error}>{error}</div>}
      {success && <div className={styles.success}>{success}</div>}

      <div className={styles.section}>
        <h3 className={styles.sectionTitle}>Konfigurierte Stimmen pro Sprache</h3>
        <p style={{ fontSize: '0.8rem', color: '#888', marginBottom: '0.5rem' }}>
          Die Sprache wird automatisch erkannt. Hier kann pro Sprache eine bevorzugte Stimme festgelegt werden.
        </p>

        {voiceMap.length === 0 ? (
          <div className={styles.emptyHint}>
            Keine Stimmen konfiguriert. Die Standardstimme wird fuer alle Sprachen verwendet.
          </div>
        ) : (
          <table className={styles.voiceTable}>
            <thead>
              <tr>
                <th>Sprache</th>
                <th>Stimme</th>
                <th></th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {voiceMap.map(entry => (
                <tr key={entry.language}>
                  <td>{_getLanguageName(entry.language)}</td>
                  <td>{entry.voiceName || 'Standard'}</td>
                  <td>
                    <button
                      className={styles.testBtn}
                      style={{ padding: '0.25rem 0.5rem', fontSize: '0.75rem' }}
                      onClick={() => _handleTestVoice(entry.language, entry.voiceName)}
                      disabled={testing === entry.language}
                    >
                      {testing === entry.language ? '...' : 'Test'}
                    </button>
                  </td>
                  <td>
                    <button className={styles.removeBtn} onClick={() => _handleRemoveEntry(entry.language)}>
                      Entfernen
                    </button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>

      <div className={styles.section}>
        <h3 className={styles.sectionTitle}>Stimme hinzufuegen / aendern</h3>

        <div className={styles.field}>
          <label className={styles.label}>Sprache</label>
          <select
            className={styles.select}
            value={addLanguage}
            onChange={e => setAddLanguage(e.target.value)}
          >
            {_displayLanguages.map((lang: any) => (
              <option key={lang.code || lang} value={lang.code || lang}>
                {lang.name || lang.code || lang}
              </option>
            ))}
          </select>
        </div>

        <div className={styles.field}>
          <label className={styles.label}>Stimme</label>
          <div className={styles.voiceRow}>
            <select
              className={styles.select}
              value={addVoiceName}
              onChange={e => setAddVoiceName(e.target.value)}
              disabled={loadingVoices}
            >
              <option value="">Standard</option>
              {addVoices.map((v: any) => (
                <option key={v.name || v} value={v.name || v}>
                  {v.displayName || v.name || v}
                </option>
              ))}
            </select>
            <button
              className={styles.testBtn}
              onClick={() => _handleTestVoice(addLanguage, addVoiceName)}
              disabled={testing !== null}
            >
              {testing === addLanguage ? '...' : 'Testen'}
            </button>
          </div>
        </div>

        <button className={styles.addBtn} onClick={_handleAddEntry}>
          Stimme zuweisen
        </button>
      </div>

      <button className={styles.saveBtn} onClick={_handleSave} disabled={saving}>
        {saving ? 'Speichern...' : 'Einstellungen speichern'}
      </button>
    </div>
  );
};

export default WorkspaceSettings;
