/**
 * SettingsScreen - Einstellungen und Verbindungsverwaltung
 *
 * QR-Scanner fuer Pairing, Moduswahl, GPS-Toggle, Log-Viewer.
 */

import React, { useState, useEffect, useCallback, useRef } from 'react';
import {
  View,
  Text,
  TextInput,
  TouchableOpacity,
  ScrollView,
  Switch,
  StyleSheet,
  Alert,
  Platform,
  ToastAndroid,
  ActivityIndicator,
  Modal,
  PermissionsAndroid,
} from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import RNFS from 'react-native-fs';
import DocumentPicker from 'react-native-document-picker';
import rvs, { ConnectionState, RVSMessage, ConnectionConfig, ConnectionLogEntry } from '../services/rvs';
import {
  TTS_PREROLL_DEFAULT_SEC,
  TTS_PREROLL_MIN_SEC,
  TTS_PREROLL_MAX_SEC,
  TTS_PREROLL_STORAGE_KEY,
  VAD_SILENCE_DEFAULT_SEC,
  VAD_SILENCE_MIN_SEC,
  VAD_SILENCE_MAX_SEC,
  VAD_SILENCE_STORAGE_KEY,
  CONV_WINDOW_DEFAULT_SEC,
  CONV_WINDOW_MIN_SEC,
  CONV_WINDOW_MAX_SEC,
  CONV_WINDOW_STORAGE_KEY,
  MAX_RECORDING_DEFAULT_SEC,
  MAX_RECORDING_MIN_SEC,
  MAX_RECORDING_MAX_SEC,
  MAX_RECORDING_STORAGE_KEY,
  VAD_SILENCE_DB_DEFAULT,
  VAD_SILENCE_DB_MIN,
  VAD_SILENCE_DB_MAX,
  VAD_SILENCE_DB_OVERRIDE_KEY,
  TTS_SPEED_DEFAULT,
  TTS_SPEED_MIN,
  TTS_SPEED_MAX,
  TTS_SPEED_STORAGE_KEY,
} from '../services/audio';
import {
  isWakeReadySoundEnabled,
  setWakeReadySoundEnabled,
  playWakeReadySound,
} from '../services/wakeReadySound';
import wakeWordService, {
  WAKE_KEYWORDS,
  KEYWORD_LABELS,
  DEFAULT_KEYWORD,
  WAKE_KEYWORD_STORAGE,
} from '../services/wakeword';
import ModeSelector from '../components/ModeSelector';
import QRScanner from '../components/QRScanner';
import VoiceCloneModal from '../components/VoiceCloneModal';
import updateService from '../services/updater';

const STORAGE_PATH_KEY = 'aria_attachment_storage_path';
const DEFAULT_STORAGE_PATH = `${RNFS.DocumentDirectoryPath}/chat_attachments`;

// --- Typen ---

interface LogEntry {
  id: string;
  timestamp: number;
  source: string;
  message: string;
  level: 'info' | 'warn' | 'error';
}

interface EventEntry {
  id: string;
  timestamp: number;
  title: string;
  description: string;
}

type LogTab = 'live' | 'events';

// Settings-Sub-Screens. Reihenfolge im Hauptmenue.
const SETTINGS_SECTIONS = [
  { id: 'connection',   icon: '🔌', label: 'Verbindung',     desc: 'Server, Token, Status, Verbindungslog' },
  { id: 'general',      icon: '⚙️', label: 'Allgemein',      desc: 'Betriebsmodus, GPS-Standort' },
  { id: 'voice_input',  icon: '🎙️', label: 'Spracheingabe',  desc: 'Stille-Toleranz, Aufnahmedauer' },
  { id: 'wake_word',    icon: '👂', label: 'Wake-Word',      desc: 'Wake-Word-Auswahl' },
  { id: 'voice_output', icon: '🔊', label: 'Sprachausgabe',  desc: 'Stimmen, Pre-Roll, Geschwindigkeit' },
  { id: 'storage',      icon: '📁', label: 'Speicher',       desc: 'Anhang-Speicherort, Auto-Download' },
  { id: 'protocol',     icon: '📜', label: 'Protokoll',      desc: 'Privatsphaere, Backup' },
  { id: 'about',        icon: 'ℹ️', label: 'Ueber',          desc: 'App-Version, Update' },
] as const;

// Container-Farben fuer Live-Logs
const SOURCE_COLORS: Record<string, string> = {
  'aria-core': '#4A9EFF',   // Blau
  bridge: '#FFD60A',        // Gelb
  proxy: '#FFFFFF',         // Weiss
  rvs: '#34C759',           // Gruen
  default: '#8888AA',       // Grau
};

// --- Komponente ---

const SettingsScreen: React.FC = () => {
  const [connectionState, setConnectionState] = useState<ConnectionState>('disconnected');
  const [manualToken, setManualToken] = useState('');
  const [manualHost, setManualHost] = useState('');
  const [manualPort, setManualPort] = useState('8765');
  const [currentMode, setCurrentMode] = useState('normal');
  const [gpsEnabled, setGpsEnabled] = useState(false);
  const [scannerVisible, setScannerVisible] = useState(false);
  const [logTab, setLogTab] = useState<LogTab>('live');
  const [logs, setLogs] = useState<LogEntry[]>([]);
  const [events, setEvents] = useState<EventEntry[]>([]);
  const [connLog, setConnLog] = useState<ConnectionLogEntry[]>(rvs.getConnectionLog());
  const [storagePath, setStoragePath] = useState(DEFAULT_STORAGE_PATH);
  const [autoDownload, setAutoDownload] = useState(true);
  const [storageSize, setStorageSize] = useState('...');
  const [ttsEnabled, setTtsEnabled] = useState(true);
  const [ttsPrerollSec, setTtsPrerollSec] = useState<number>(TTS_PREROLL_DEFAULT_SEC);
  const [vadSilenceSec, setVadSilenceSec] = useState<number>(VAD_SILENCE_DEFAULT_SEC);
  const [convWindowSec, setConvWindowSec] = useState<number>(CONV_WINDOW_DEFAULT_SEC);
  const [maxRecordingSec, setMaxRecordingSec] = useState<number>(MAX_RECORDING_DEFAULT_SEC);
  // null = automatisch (adaptive Baseline), sonst manueller dB-Override
  const [vadSilenceDb, setVadSilenceDb] = useState<number | null>(null);
  const [showVadInfo, setShowVadInfo] = useState(false);
  const [apkCacheInfo, setApkCacheInfo] = useState<{count: number, totalMB: number} | null>(null);
  const [ttsSpeed, setTtsSpeed] = useState<number>(TTS_SPEED_DEFAULT);
  const [wakeKeyword, setWakeKeyword] = useState<string>(DEFAULT_KEYWORD);
  const [wakeStatus, setWakeStatus] = useState<string>('');
  const [wakeReadySound, setWakeReadySound] = useState<boolean>(true);
  const [editingPath, setEditingPath] = useState(false);
  const [xttsVoice, setXttsVoice] = useState('');
  const [loadingVoice, setLoadingVoice] = useState<string | null>(null);
  const [availableVoices, setAvailableVoices] = useState<Array<{name: string, size: number}>>([]);
  const [voiceCloneVisible, setVoiceCloneVisible] = useState(false);
  const [tempPath, setTempPath] = useState('');
  // Sub-Screen Navigation: null = Hauptmenue, sonst eine der Section-IDs.
  // So bleibt aller geteilte State im selben Component-Closure und wir
  // brauchen keine react-navigation-Stack-Setup.
  const [currentSection, setCurrentSection] = useState<string | null>(null);

  let logIdCounter = 0;

  // Gespeicherte Config in die Felder laden
  useEffect(() => {
    const config = rvs.getConfig();
    if (config) {
      setManualHost(config.host);
      setManualPort(String(config.port));
      setManualToken(config.token);
    }
    // Speicherpfad + Auto-Download laden
    AsyncStorage.getItem(STORAGE_PATH_KEY).then(saved => {
      if (saved) setStoragePath(saved);
    });
    AsyncStorage.getItem('aria_auto_download').then(saved => {
      if (saved !== null) setAutoDownload(saved === 'true');
    });
    AsyncStorage.getItem('aria_tts_enabled').then(saved => {
      if (saved !== null) setTtsEnabled(saved === 'true');
    });
    AsyncStorage.getItem('aria_gps_enabled').then(saved => {
      if (saved !== null) setGpsEnabled(saved === 'true');
    });
    AsyncStorage.getItem(TTS_PREROLL_STORAGE_KEY).then(saved => {
      if (saved != null) {
        const n = parseFloat(saved);
        if (isFinite(n) && n >= TTS_PREROLL_MIN_SEC && n <= TTS_PREROLL_MAX_SEC) {
          setTtsPrerollSec(n);
        }
      }
    });
    AsyncStorage.getItem(VAD_SILENCE_STORAGE_KEY).then(saved => {
      if (saved != null) {
        const n = parseFloat(saved);
        if (isFinite(n) && n >= VAD_SILENCE_MIN_SEC && n <= VAD_SILENCE_MAX_SEC) {
          setVadSilenceSec(n);
        }
      }
    });
    AsyncStorage.getItem(CONV_WINDOW_STORAGE_KEY).then(saved => {
      if (saved != null) {
        const n = parseFloat(saved);
        if (isFinite(n) && n >= CONV_WINDOW_MIN_SEC && n <= CONV_WINDOW_MAX_SEC) {
          setConvWindowSec(n);
        }
      }
    });
    AsyncStorage.getItem(MAX_RECORDING_STORAGE_KEY).then(saved => {
      if (saved != null) {
        const n = parseFloat(saved);
        if (isFinite(n) && n >= MAX_RECORDING_MIN_SEC && n <= MAX_RECORDING_MAX_SEC) {
          setMaxRecordingSec(n);
        }
      }
    });
    AsyncStorage.getItem(VAD_SILENCE_DB_OVERRIDE_KEY).then(saved => {
      if (saved != null && saved !== '') {
        const n = parseFloat(saved);
        if (isFinite(n) && n >= VAD_SILENCE_DB_MIN && n <= VAD_SILENCE_DB_MAX) {
          setVadSilenceDb(n);
        }
      }
    });
    AsyncStorage.getItem(TTS_SPEED_STORAGE_KEY).then(saved => {
      if (saved != null) {
        const n = parseFloat(saved);
        if (isFinite(n) && n >= TTS_SPEED_MIN && n <= TTS_SPEED_MAX) setTtsSpeed(n);
      }
    });
    AsyncStorage.getItem(WAKE_KEYWORD_STORAGE).then(saved => {
      if (saved && (WAKE_KEYWORDS as readonly string[]).includes(saved)) setWakeKeyword(saved);
    });
    isWakeReadySoundEnabled().then(setWakeReadySound);
    updateService.getApkCacheSize().then(setApkCacheInfo).catch(() => {});
    AsyncStorage.getItem('aria_xtts_voice').then(saved => {
      if (saved) setXttsVoice(saved);
    });
    // Voice-Liste vom XTTS-Server holen (via RVS)
    rvs.send('xtts_list_voices' as any, {});
  }, []);

  // Speichergroesse berechnen
  useEffect(() => {
    const calcSize = async () => {
      try {
        const exists = await RNFS.exists(storagePath);
        if (!exists) { setStorageSize('0 KB'); return; }
        const items = await RNFS.readDir(storagePath);
        const totalBytes = items.reduce((sum, f) => sum + (f.size || 0), 0);
        if (totalBytes > 1024 * 1024) {
          setStorageSize(`${(totalBytes / 1024 / 1024).toFixed(1)} MB (${items.length} Dateien)`);
        } else {
          setStorageSize(`${Math.round(totalBytes / 1024)} KB (${items.length} Dateien)`);
        }
      } catch { setStorageSize('nicht verfuegbar'); }
    };
    calcSize();
  }, [storagePath]);

  const saveStoragePath = useCallback(async (newPath: string) => {
    const clean = newPath.trim();
    if (!clean) return;
    await AsyncStorage.setItem(STORAGE_PATH_KEY, clean);
    setStoragePath(clean);
    setEditingPath(false);
    Alert.alert('Gespeichert', `Neuer Speicherort:\n${clean}\n\nWird ab der naechsten Nachricht verwendet.`);
  }, []);

  const showPathPicker = useCallback(() => {
    Alert.alert(
      'Speicherort waehlen',
      'Wo sollen Anhaenge gespeichert werden?',
      [
        {
          text: 'Ordner auswaehlen...',
          onPress: async () => {
            try {
              const result = await DocumentPicker.pickDirectory();
              if (result?.uri) {
                // SAF URI decodieren (content://com.android.externalstorage...)
                const decoded = decodeURIComponent(result.uri);
                // Versuche einen lesbaren Pfad zu extrahieren
                const match = decoded.match(/primary[:%]3A(.+)/);
                const readablePath = match
                  ? `/storage/emulated/0/${match[1].replace(/%2F|%3A/g, '/')}`
                  : decoded;
                saveStoragePath(readablePath);
              }
            } catch (e: any) {
              if (!DocumentPicker.isCancel(e)) {
                Alert.alert('Fehler', 'Ordnerauswahl fehlgeschlagen');
              }
            }
          },
        },
        {
          text: 'App-intern (Standard)',
          onPress: () => saveStoragePath(DEFAULT_STORAGE_PATH),
        },
        {
          text: 'Pfad manuell eingeben',
          onPress: () => { setTempPath(storagePath); setEditingPath(true); },
        },
        { text: 'Abbrechen', style: 'cancel' as const },
      ],
    );
  }, [storagePath]);

  const clearStorageCache = useCallback(async () => {
    Alert.alert(
      'Cache loeschen',
      `Alle lokalen Anhaenge in\n${storagePath}\nloeschen?\n\nDateien koennen ueber RVS erneut heruntergeladen werden.`,
      [
        { text: 'Abbrechen', style: 'cancel' },
        {
          text: 'Loeschen',
          style: 'destructive',
          onPress: async () => {
            try {
              const exists = await RNFS.exists(storagePath);
              if (exists) await RNFS.unlink(storagePath);
              await RNFS.mkdir(storagePath);
              setStorageSize('0 KB (0 Dateien)');
              Alert.alert('Erledigt', 'Cache geleert. Anhaenge werden bei Bedarf neu geladen.');
            } catch (e: any) {
              Alert.alert('Fehler', e.message);
            }
          },
        },
      ],
    );
  }, [storagePath]);

  // RVS-Nachrichten und Verbindungslog abonnieren
  useEffect(() => {
    const unsubState = rvs.onStateChange(setConnectionState);
    setConnectionState(rvs.getState());

    const unsubLog = rvs.onLog((entry) => {
      setConnLog(prev => [...prev.slice(-99), entry]);
    });

    const unsubMessage = rvs.onMessage((message: RVSMessage) => {
      if (message.type === 'log') {
        const entry: LogEntry = {
          id: `log_${Date.now()}_${logIdCounter++}`,
          timestamp: message.timestamp,
          source: (message.payload.source as string) || 'default',
          message: (message.payload.message as string) || '',
          level: (message.payload.level as 'info' | 'warn' | 'error') || 'info',
        };
        setLogs(prev => [...prev.slice(-200), entry]); // Max 200 Eintraege behalten
      }

      if (message.type === 'event') {
        const entry: EventEntry = {
          id: `evt_${Date.now()}_${logIdCounter++}`,
          timestamp: message.timestamp,
          title: (message.payload.title as string) || '',
          description: (message.payload.description as string) || '',
        };
        setEvents(prev => [...prev.slice(-100), entry]);
      }

      // Modus-Bestaetigung
      if (message.type === 'mode') {
        const mode = message.payload.mode as string;
        if (mode) setCurrentMode(mode);
      }

      // XTTS-Voice-Liste
      if (message.type === ('xtts_voices_list' as any)) {
        const voices = ((message.payload as any).voices || []) as Array<{name: string, size: number}>;
        setAvailableVoices(voices);
      }

      // Voice wurde gespeichert → Liste neu laden + ggf. auswaehlen
      if (message.type === ('xtts_voice_saved' as any)) {
        const name = (message.payload as any).name as string;
        if (name) {
          setXttsVoice(name);
          AsyncStorage.setItem('aria_xtts_voice', name);
        }
        rvs.send('xtts_list_voices' as any, {});
      }

      // Diagnostic-Voice-Wechsel → lokale App-Stimme auf den neuen Default zuruecksetzen.
      // Zusaetzlich Preload triggern, damit der User weiss wann's geladen ist.
      if (message.type === ('config' as any)) {
        const newVoice = ((message.payload as any).xttsVoice as string) ?? '';
        setXttsVoice(newVoice);
        AsyncStorage.setItem('aria_xtts_voice', newVoice);
        if (newVoice) {
          setLoadingVoice(newVoice);
        }
      }

      // XTTS-Bridge meldet: Stimme fertig geladen
      if (message.type === ('voice_ready' as any)) {
        const v = ((message.payload as any).voice as string) ?? '';
        const err = (message.payload as any).error as string | undefined;
        const ms = (message.payload as any).loadMs as number | undefined;
        setLoadingVoice(null);
        if (err) {
          ToastAndroid.show(`Stimme "${v}" konnte nicht geladen werden: ${err}`, ToastAndroid.LONG);
        } else {
          const suffix = ms ? ` (${(ms / 1000).toFixed(1)}s)` : '';
          ToastAndroid.show(`Stimme "${v || 'Standard'}" bereit${suffix}`, ToastAndroid.SHORT);
        }
      }
    });

    return () => {
      unsubState();
      unsubMessage();
      unsubLog();
    };
  }, []);

  // --- QR-Code scannen ---

  const openQRScanner = useCallback(() => {
    setScannerVisible(true);
  }, []);

  const handleQRScan = useCallback((config: ConnectionConfig) => {
    setScannerVisible(false);

    // Felder im UI aktualisieren
    setManualHost(config.host);
    setManualPort(String(config.port));
    setManualToken(config.token);

    // Direkt verbinden
    rvs.setConfig(config);
    rvs.connect();

    Alert.alert(
      'Pairing erfolgreich',
      `Verbinde mit ${config.host}:${config.port}...`,
    );
  }, []);

  // --- Manuelle Verbindung ---

  const connectManually = useCallback(() => {
    if (!manualHost.trim() || !manualToken.trim()) {
      Alert.alert('Fehler', 'Host und Token muessen angegeben werden.');
      return;
    }

    const config: ConnectionConfig = {
      host: manualHost.trim(),
      port: parseInt(manualPort, 10) || 8765,
      token: manualToken.trim(),
      useTLS: true,
    };

    rvs.setConfig(config);
    rvs.connect();
  }, [manualHost, manualPort, manualToken]);

  const disconnectRVS = useCallback(() => {
    rvs.disconnect();
  }, []);

  // --- GPS Toggle ---

  const handleGPSToggle = useCallback(async (value: boolean) => {
    if (value && Platform.OS === 'android') {
      try {
        const granted = await PermissionsAndroid.request(
          PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
          {
            title: 'ARIA — Standort an Anfragen anhaengen',
            message: 'Damit ARIA bei Anfragen wie "Wo ist der naechste...?" den '
              + 'Standort kennt, darf die App den ungefaehren Standort lesen. '
              + 'Wird nur bei jeder Anfrage einmal abgerufen, nicht im Hintergrund.',
            buttonPositive: 'Erlauben',
            buttonNegative: 'Abbrechen',
          },
        );
        if (granted !== PermissionsAndroid.RESULTS.GRANTED) {
          ToastAndroid.show('Standort-Berechtigung abgelehnt', ToastAndroid.SHORT);
          return;
        }
      } catch (err) {
        console.warn('[Settings] GPS-Permission Request gescheitert:', err);
        return;
      }
    }
    setGpsEnabled(value);
    AsyncStorage.setItem('aria_gps_enabled', String(value)).catch(() => {});
  }, []);

  // --- XTTS Voice ---

  const selectVoice = useCallback((voiceName: string) => {
    setXttsVoice(voiceName);
    AsyncStorage.setItem('aria_xtts_voice', voiceName);
    // Preload nur fuer Custom-Voices — "Standard" braucht keinen Ladevorgang
    if (voiceName) {
      setLoadingVoice(voiceName);
      rvs.send('voice_preload' as any, { voice: voiceName, source: 'app' });
    } else {
      setLoadingVoice(null);
    }
  }, []);

  const deleteVoice = useCallback((name: string) => {
    Alert.alert(
      'Stimme loeschen',
      `Stimme "${name}" vom Server endgueltig loeschen?\nAlle Apps verlieren sie.`,
      [
        { text: 'Abbrechen', style: 'cancel' },
        {
          text: 'Loeschen',
          style: 'destructive',
          onPress: () => {
            rvs.send('xtts_delete_voice' as any, { name });
            if (xttsVoice === name) {
              setXttsVoice('');
              AsyncStorage.setItem('aria_xtts_voice', '');
            }
            // Liste nach kurzer Wartezeit neu laden (XTTS-Bridge schickt eh neue Liste)
            setTimeout(() => rvs.send('xtts_list_voices' as any, {}), 500);
          },
        },
      ],
    );
  }, [xttsVoice]);

  // --- Modus aendern ---

  const handleModeChange = useCallback((modeId: string) => {
    setCurrentMode(modeId);
  }, []);

  // --- Zeitformat ---

  const formatTime = (ts: number): string => {
    return new Date(ts).toLocaleTimeString('de-DE', {
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit',
    });
  };

  // --- Verbindungsstatus ---

  const connectionDotColor =
    connectionState === 'connected' ? '#34C759' :
    connectionState === 'connecting' ? '#FFD60A' : '#FF3B30';

  const connectionLabel =
    connectionState === 'connected' ? 'Verbunden' :
    connectionState === 'connecting' ? 'Verbinde...' : 'Getrennt';

  return (
    <>
    <QRScanner
      visible={scannerVisible}
      onScan={handleQRScan}
      onClose={() => setScannerVisible(false)}
    />
    <VoiceCloneModal
      visible={voiceCloneVisible}
      onClose={() => setVoiceCloneVisible(false)}
    />
    <ScrollView style={styles.container} contentContainerStyle={styles.content}>

      {currentSection === null && (
        <>
          {SETTINGS_SECTIONS.map(s => (
            <TouchableOpacity
              key={s.id}
              style={styles.menuItem}
              onPress={() => setCurrentSection(s.id)}
            >
              <Text style={styles.menuItemIcon}>{s.icon}</Text>
              <View style={styles.menuItemTextWrap}>
                <Text style={styles.menuItemLabel}>{s.label}</Text>
                <Text style={styles.menuItemDesc}>{s.desc}</Text>
              </View>
              <Text style={styles.menuItemChevron}>›</Text>
            </TouchableOpacity>
          ))}
        </>
      )}

      {currentSection !== null && (
        <TouchableOpacity
          style={styles.subScreenHeader}
          onPress={() => setCurrentSection(null)}
        >
          <Text style={styles.subScreenBack}>‹</Text>
          <Text style={styles.subScreenTitle}>
            {SETTINGS_SECTIONS.find(s => s.id === currentSection)?.label || ''}
          </Text>
        </TouchableOpacity>
      )}

      {/* === Verbindung === */}
      {currentSection === 'connection' && (<>
      <Text style={styles.sectionTitle}>Verbindung</Text>
      <View style={styles.card}>
        {/* Status-Anzeige */}
        <View style={styles.statusRow}>
          <View style={[styles.statusDot, { backgroundColor: connectionDotColor }]} />
          <Text style={styles.statusLabel}>{connectionLabel}</Text>
          {connectionState === 'connected' && (
            <TouchableOpacity style={styles.disconnectButton} onPress={disconnectRVS}>
              <Text style={styles.disconnectText}>Trennen</Text>
            </TouchableOpacity>
          )}
        </View>

        {/* QR-Scanner */}
        <TouchableOpacity style={styles.qrButton} onPress={openQRScanner}>
          <Text style={styles.qrIcon}>{'\uD83D\uDCF1'}</Text>
          <Text style={styles.qrText}>QR-Code scannen (Pairing)</Text>
        </TouchableOpacity>

        {/* Manuelle Eingabe */}
        <Text style={styles.inputLabel}>Host</Text>
        <TextInput
          style={styles.input}
          value={manualHost}
          onChangeText={setManualHost}
          placeholder="z.B. aria.example.com"
          placeholderTextColor="#555570"
          autoCapitalize="none"
        />

        <Text style={styles.inputLabel}>Port</Text>
        <TextInput
          style={styles.input}
          value={manualPort}
          onChangeText={setManualPort}
          placeholder="8765"
          placeholderTextColor="#555570"
          keyboardType="numeric"
        />

        <Text style={styles.inputLabel}>Token</Text>
        <TextInput
          style={styles.input}
          value={manualToken}
          onChangeText={setManualToken}
          placeholder="Verbindungs-Token"
          placeholderTextColor="#555570"
          autoCapitalize="none"
          secureTextEntry
        />

        <TouchableOpacity style={styles.connectButton} onPress={connectManually}>
          <Text style={styles.connectButtonText}>Verbinden</Text>
        </TouchableOpacity>
      </View>

      {/* === Verbindungslog === */}
      <Text style={styles.sectionTitle}>Verbindungslog</Text>
      <View style={styles.card}>
        <ScrollView
          style={styles.connLogScroll}
          nestedScrollEnabled={true}
          ref={(ref) => {
            // Auto-Scroll nach unten bei neuen Eintraegen
            if (ref && connLog.length > 0) {
              setTimeout(() => ref.scrollToEnd({ animated: false }), 50);
            }
          }}
        >
          {connLog.length > 0 ? (
            connLog.slice(-50).map((entry, idx) => (
              <View key={`cl_${idx}`} style={styles.logEntry}>
                <Text style={styles.logTime}>{formatTime(entry.timestamp)}</Text>
                <Text
                  style={[
                    styles.logMessage,
                    entry.level === 'error' && styles.logError,
                    entry.level === 'warn' && styles.logWarn,
                  ]}
                  numberOfLines={3}
                >
                  {entry.message}
                </Text>
              </View>
            ))
          ) : (
            <Text style={styles.emptyLog}>Noch keine Verbindungsversuche</Text>
          )}
        </ScrollView>
        <TouchableOpacity
          style={styles.clearButton}
          onPress={() => setConnLog([])}
        >
          <Text style={styles.clearButtonText}>Log l{'\u00F6'}schen</Text>
        </TouchableOpacity>
      </View>
      </>)}

      {/* === Modus === */}
      {currentSection === 'general' && (<>
      <Text style={styles.sectionTitle}>Betriebsmodus</Text>
      <View style={styles.card}>
        <ModeSelector currentModeId={currentMode} onModeChange={handleModeChange} />
      </View>

      {/* === GPS === */}
      <Text style={styles.sectionTitle}>Standort</Text>
      <View style={styles.card}>
        <View style={styles.toggleRow}>
          <View style={styles.toggleInfo}>
            <Text style={styles.toggleLabel}>GPS-Position mitsenden</Text>
            <Text style={styles.toggleHint}>
              Position (lat/lon) wird mit jeder Nachricht an ARIA mitgeschickt.
              Sie sieht's nur intern und nutzt es bei standortbezogenen Fragen
              ("wo bin ich?", "Wetter hier?"), erwaehnt es sonst nicht.
              Im Chat-Verlauf bleibt die Bubble unveraendert — nur ARIAs
              Antwort kann darauf eingehen.
            </Text>
          </View>
          <Switch
            value={gpsEnabled}
            onValueChange={handleGPSToggle}
            trackColor={{ false: '#2A2A3E', true: '#0096FF' }}
            thumbColor={gpsEnabled ? '#FFFFFF' : '#666680'}
          />
        </View>
      </View>
      </>)}

      {/* === Spracheingabe (geraetelokal) === */}
      {currentSection === 'voice_input' && (<>
      <Text style={styles.sectionTitle}>Spracheingabe</Text>
      <View style={styles.card}>
        <Text style={styles.toggleLabel}>Stille-Toleranz</Text>
        <Text style={styles.toggleHint}>
          Wie lange du eine Sprechpause machen darfst, bevor die Aufnahme
          automatisch beendet und gesendet wird. Hoeher = mehr Zeit zum
          Nachdenken; niedriger = schnelleres Senden.
          Default: {VAD_SILENCE_DEFAULT_SEC.toFixed(1)}s.
        </Text>
        <View style={styles.prerollRow}>
          <TouchableOpacity
            style={styles.prerollButton}
            onPress={() => {
              const next = Math.max(VAD_SILENCE_MIN_SEC, Math.round((vadSilenceSec - 0.5) * 10) / 10);
              setVadSilenceSec(next);
              AsyncStorage.setItem(VAD_SILENCE_STORAGE_KEY, String(next));
            }}
            disabled={vadSilenceSec <= VAD_SILENCE_MIN_SEC}
          >
            <Text style={styles.prerollButtonText}>−0.5</Text>
          </TouchableOpacity>
          <Text style={styles.prerollValue}>{vadSilenceSec.toFixed(1)} s</Text>
          <TouchableOpacity
            style={styles.prerollButton}
            onPress={() => {
              const next = Math.min(VAD_SILENCE_MAX_SEC, Math.round((vadSilenceSec + 0.5) * 10) / 10);
              setVadSilenceSec(next);
              AsyncStorage.setItem(VAD_SILENCE_STORAGE_KEY, String(next));
            }}
            disabled={vadSilenceSec >= VAD_SILENCE_MAX_SEC}
          >
            <Text style={styles.prerollButtonText}>+0.5</Text>
          </TouchableOpacity>
        </View>

        <Text style={[styles.toggleLabel, {marginTop: 24}]}>Konversations-Fenster</Text>
        <Text style={styles.toggleHint}>
          Im Gespraechsmodus (Ohr-Button): nach ARIA's Antwort hast du so lange
          Zeit, weiter zu sprechen, bevor die Konversation automatisch beendet wird.
          Sprichst du nichts → Mikrofon zu.
          Default: {CONV_WINDOW_DEFAULT_SEC.toFixed(1)}s.
        </Text>
        <View style={styles.prerollRow}>
          <TouchableOpacity
            style={styles.prerollButton}
            onPress={() => {
              const next = Math.max(CONV_WINDOW_MIN_SEC, Math.round((convWindowSec - 1) * 10) / 10);
              setConvWindowSec(next);
              AsyncStorage.setItem(CONV_WINDOW_STORAGE_KEY, String(next));
            }}
            disabled={convWindowSec <= CONV_WINDOW_MIN_SEC}
          >
            <Text style={styles.prerollButtonText}>−1</Text>
          </TouchableOpacity>
          <Text style={styles.prerollValue}>{convWindowSec.toFixed(0)} s</Text>
          <TouchableOpacity
            style={styles.prerollButton}
            onPress={() => {
              const next = Math.min(CONV_WINDOW_MAX_SEC, Math.round((convWindowSec + 1) * 10) / 10);
              setConvWindowSec(next);
              AsyncStorage.setItem(CONV_WINDOW_STORAGE_KEY, String(next));
            }}
            disabled={convWindowSec >= CONV_WINDOW_MAX_SEC}
          >
            <Text style={styles.prerollButtonText}>+1</Text>
          </TouchableOpacity>
        </View>

        <Text style={[styles.toggleLabel, {marginTop: 24}]}>Maximale Aufnahmedauer</Text>
        <Text style={styles.toggleHint}>
          Notbremse: nach so vielen Minuten wird die Aufnahme automatisch beendet,
          auch wenn keine Stille erkannt wurde. Nuetzlich fuer lange Erklaerungen
          oder Diktate. Default: {Math.round(MAX_RECORDING_DEFAULT_SEC / 60)} Min, max {Math.round(MAX_RECORDING_MAX_SEC / 60)} Min.
        </Text>
        <View style={styles.prerollRow}>
          <TouchableOpacity
            style={styles.prerollButton}
            onPress={() => {
              const next = Math.max(MAX_RECORDING_MIN_SEC, maxRecordingSec - 60);
              setMaxRecordingSec(next);
              AsyncStorage.setItem(MAX_RECORDING_STORAGE_KEY, String(next));
            }}
            disabled={maxRecordingSec <= MAX_RECORDING_MIN_SEC}
          >
            <Text style={styles.prerollButtonText}>−1m</Text>
          </TouchableOpacity>
          <Text style={styles.prerollValue}>{Math.round(maxRecordingSec / 60)} min</Text>
          <TouchableOpacity
            style={styles.prerollButton}
            onPress={() => {
              const next = Math.min(MAX_RECORDING_MAX_SEC, maxRecordingSec + 60);
              setMaxRecordingSec(next);
              AsyncStorage.setItem(MAX_RECORDING_STORAGE_KEY, String(next));
            }}
            disabled={maxRecordingSec >= MAX_RECORDING_MAX_SEC}
          >
            <Text style={styles.prerollButtonText}>+1m</Text>
          </TouchableOpacity>
        </View>

        <View style={{flexDirection: 'row', alignItems: 'center', marginTop: 24, gap: 8}}>
          <Text style={styles.toggleLabel}>Stille-Pegel (dB)</Text>
          <TouchableOpacity onPress={() => setShowVadInfo(true)} style={styles.infoBtn}>
            <Text style={styles.infoBtnText}>i</Text>
          </TouchableOpacity>
        </View>
        <Text style={styles.toggleHint}>
          Welcher Mikro-Pegel als "Stille" gilt. Standard: automatisch (Baseline aus
          den ersten 500ms). Manuell setzen wenn Auto nicht zuverlaessig greift.
        </Text>
        <View style={styles.prerollRow}>
          <TouchableOpacity
            style={styles.prerollButton}
            onPress={() => {
              const next = vadSilenceDb == null
                ? VAD_SILENCE_DB_DEFAULT - 1
                : Math.max(VAD_SILENCE_DB_MIN, vadSilenceDb - 1);
              setVadSilenceDb(next);
              AsyncStorage.setItem(VAD_SILENCE_DB_OVERRIDE_KEY, String(next));
            }}
          >
            <Text style={styles.prerollButtonText}>−1</Text>
          </TouchableOpacity>
          <Text style={styles.prerollValue}>
            {vadSilenceDb == null ? 'auto' : `${vadSilenceDb} dB`}
          </Text>
          <TouchableOpacity
            style={styles.prerollButton}
            onPress={() => {
              const next = vadSilenceDb == null
                ? VAD_SILENCE_DB_DEFAULT + 1
                : Math.min(VAD_SILENCE_DB_MAX, vadSilenceDb + 1);
              setVadSilenceDb(next);
              AsyncStorage.setItem(VAD_SILENCE_DB_OVERRIDE_KEY, String(next));
            }}
          >
            <Text style={styles.prerollButtonText}>+1</Text>
          </TouchableOpacity>
        </View>
        {vadSilenceDb != null && (
          <TouchableOpacity
            onPress={() => {
              setVadSilenceDb(null);
              AsyncStorage.removeItem(VAD_SILENCE_DB_OVERRIDE_KEY);
            }}
            style={{alignSelf: 'center', marginTop: 8, paddingVertical: 6, paddingHorizontal: 12}}
          >
            <Text style={{color: '#0096FF', fontSize: 13}}>↻ Auf automatisch zuruecksetzen</Text>
          </TouchableOpacity>
        )}
      </View>

      <Modal
        visible={showVadInfo}
        transparent
        animationType="fade"
        onRequestClose={() => setShowVadInfo(false)}
      >
        <View style={styles.modalOverlay}>
          <View style={styles.modalCard}>
            <Text style={styles.modalTitle}>Stille-Pegel (dB)</Text>
            <Text style={styles.modalText}>
              Lautstaerken werden in Dezibel (dB) gemessen — negative Werte, je
              hoeher (naeher an 0), desto lauter.{'\n\n'}
              <Text style={{fontWeight: '700'}}>Standard:</Text> automatisch.
              Die App misst die ersten 500ms Hintergrundpegel und setzt die
              Stille-Schwelle auf Baseline + 6 dB. Funktioniert in den meisten
              Umgebungen.{'\n\n'}
              <Text style={{fontWeight: '700'}}>Manuell:</Text> Pegel unter dem
              eingestellten Wert gilt als "Stille" → Aufnahme stoppt.{'\n\n'}
              <Text style={{fontWeight: '700'}}>Faustregel:</Text>{'\n'}
              • <Text style={{color: '#FFD60A'}}>−45 dB</Text> sehr empfindlich (stoppt schnell, auch bei Atmen){'\n'}
              • <Text style={{color: '#34C759'}}>−38 dB</Text> ausgewogen (typische Bueroumgebung){'\n'}
              • <Text style={{color: '#FF6B6B'}}>−25 dB</Text> unempfindlich (laute Umgebung, nur klare Sprache zaehlt){'\n\n'}
              <Text style={{color: '#8888AA'}}>Niedrigere Zahl (z.B. −50) = sensibler.{'\n'}
              Hoehere Zahl (z.B. −20) = robuster gegen Hintergrundlaerm,
              braucht aber lautere Sprache.</Text>
            </Text>
            <TouchableOpacity
              style={[styles.connectButton, {marginTop: 16, alignSelf: 'stretch'}]}
              onPress={() => setShowVadInfo(false)}
            >
              <Text style={styles.connectButtonText}>OK</Text>
            </TouchableOpacity>
          </View>
        </View>
      </Modal>
      </>)}

      {/* === Wake-Word (komplett on-device, openWakeWord) === */}
      {currentSection === 'wake_word' && (<>
      <Text style={styles.sectionTitle}>Wake-Word</Text>
      <View style={styles.card}>
        <Text style={styles.toggleHint}>
          Lokale Erkennung via openWakeWord (ONNX, on-device). Kein API-Key,
          kein Cloud-Roundtrip — Audio verlaesst das Geraet nicht. Wenn das Ohr
          aktiv ist, hoerst du normal mit; sagst du das Wake-Word, startet eine
          Konversation mit ARIA.
        </Text>

        <Text style={[styles.toggleLabel, {marginTop: 16}]}>Wake-Word</Text>
        <Text style={styles.toggleHint}>
          Eigene Wake-Words via openWakeWord-Notebook trainierbar (gratis).
          Custom-Upload ueber Diagnostic kommt in einer spaeteren Version.
        </Text>
        <View style={{flexDirection: 'row', flexWrap: 'wrap', gap: 6, marginTop: 8}}>
          {WAKE_KEYWORDS.map(kw => (
            <TouchableOpacity
              key={kw}
              style={[
                styles.keywordChip,
                wakeKeyword === kw && styles.keywordChipActive,
              ]}
              onPress={() => setWakeKeyword(kw)}
            >
              <Text style={[
                styles.keywordChipText,
                wakeKeyword === kw && styles.keywordChipTextActive,
              ]}>
                {KEYWORD_LABELS[kw]}
              </Text>
            </TouchableOpacity>
          ))}
        </View>

        <View style={{flexDirection: 'row', gap: 8, marginTop: 16, alignItems: 'center'}}>
          <TouchableOpacity
            style={[styles.connectButton, {flex: 1}]}
            onPress={async () => {
              setWakeStatus('Initialisiere...');
              try {
                const ok = await wakeWordService.configure(wakeKeyword);
                setWakeStatus(ok ? `✅ "${KEYWORD_LABELS[wakeKeyword as keyof typeof KEYWORD_LABELS]}" bereit` : '❌ Init-Fehler — Logs pruefen');
              } catch (err: any) {
                setWakeStatus('❌ ' + String(err?.message || err).slice(0, 80));
              }
              setTimeout(() => setWakeStatus(''), 5000);
            }}
          >
            <Text style={styles.connectButtonText}>Speichern + Aktivieren</Text>
          </TouchableOpacity>
        </View>
        {!!wakeStatus && (
          <Text style={{marginTop: 8, fontSize: 12, color: '#8888AA'}}>{wakeStatus}</Text>
        )}

        <View style={[styles.toggleRow, {marginTop: 20, borderTopWidth: 1, borderTopColor: '#1E1E2E', paddingTop: 16}]}>
          <View style={styles.toggleInfo}>
            <Text style={styles.toggleLabel}>Bereit-Sound abspielen</Text>
            <Text style={styles.toggleHint}>
              Kurzer Ding-Dong wenn das Mikro nach Wake-Word offen ist —
              akustische Bestaetigung dass du jetzt sprechen darfst.
            </Text>
          </View>
          <Switch
            value={wakeReadySound}
            onValueChange={async (val) => {
              setWakeReadySound(val);
              await setWakeReadySoundEnabled(val);
              if (val) {
                // Direkt eine Vorschau abspielen damit der User weiss wie's klingt.
                // playWakeReadySound checked das gerade gesetzte Flag — wenn val=true,
                // wird abgespielt; bei false bleibt es still.
                setTimeout(() => playWakeReadySound().catch(() => {}), 150);
              }
            }}
            trackColor={{ false: '#2A2A3E', true: '#0096FF' }}
            thumbColor={wakeReadySound ? '#FFFFFF' : '#666680'}
          />
        </View>
      </View>
      </>)}

      {/* === Sprachausgabe (geraetelokal) === */}
      {currentSection === 'voice_output' && (<>
      <Text style={styles.sectionTitle}>Sprachausgabe</Text>
      <View style={styles.card}>
        <View style={styles.toggleRow}>
          <View style={styles.toggleInfo}>
            <Text style={styles.toggleLabel}>Sprachausgabe auf diesem Geraet</Text>
            <Text style={styles.toggleHint}>
              Nur lokal — andere Geraete sind unabhaengig.
              Wenn aus, erscheint im Chat auch kein Mund-Button.
            </Text>
          </View>
          <Switch
            value={ttsEnabled}
            onValueChange={(val) => {
              setTtsEnabled(val);
              AsyncStorage.setItem('aria_tts_enabled', String(val));
            }}
            trackColor={{ false: '#2A2A3E', true: '#0096FF' }}
            thumbColor={ttsEnabled ? '#FFFFFF' : '#666680'}
          />
        </View>

        {ttsEnabled && (
          <View style={{marginTop: 20}}>
            <Text style={styles.toggleLabel}>Puffer vor Wiedergabestart</Text>
            <Text style={styles.toggleHint}>
              Wie viel Audio gesammelt wird bevor die Wiedergabe startet.
              Hoeher = robuster gegen Render-Pausen, aber mehr Startverzoegerung.
              Default: {TTS_PREROLL_DEFAULT_SEC.toFixed(1)}s.
            </Text>
            <View style={styles.prerollRow}>
              <TouchableOpacity
                style={styles.prerollButton}
                onPress={() => {
                  const next = Math.max(TTS_PREROLL_MIN_SEC, Math.round((ttsPrerollSec - 0.5) * 10) / 10);
                  setTtsPrerollSec(next);
                  AsyncStorage.setItem(TTS_PREROLL_STORAGE_KEY, String(next));
                }}
                disabled={ttsPrerollSec <= TTS_PREROLL_MIN_SEC}
              >
                <Text style={styles.prerollButtonText}>−0.5</Text>
              </TouchableOpacity>
              <Text style={styles.prerollValue}>{ttsPrerollSec.toFixed(1)} s</Text>
              <TouchableOpacity
                style={styles.prerollButton}
                onPress={() => {
                  const next = Math.min(TTS_PREROLL_MAX_SEC, Math.round((ttsPrerollSec + 0.5) * 10) / 10);
                  setTtsPrerollSec(next);
                  AsyncStorage.setItem(TTS_PREROLL_STORAGE_KEY, String(next));
                }}
                disabled={ttsPrerollSec >= TTS_PREROLL_MAX_SEC}
              >
                <Text style={styles.prerollButtonText}>+0.5</Text>
              </TouchableOpacity>
            </View>

            <Text style={[styles.toggleLabel, {marginTop: 24}]}>Sprechgeschwindigkeit</Text>
            <Text style={styles.toggleHint}>
              Wie schnell ARIA spricht. 1.0 = Normal. Niedriger = langsamer, hoeher = schneller.
              Wird an F5-TTS als speed-Param uebergeben und pro Geraet gespeichert.
              Default: {TTS_SPEED_DEFAULT.toFixed(1)}x.
            </Text>
            <View style={styles.prerollRow}>
              <TouchableOpacity
                style={styles.prerollButton}
                onPress={() => {
                  const next = Math.max(TTS_SPEED_MIN, Math.round((ttsSpeed - 0.1) * 10) / 10);
                  setTtsSpeed(next);
                  AsyncStorage.setItem(TTS_SPEED_STORAGE_KEY, String(next));
                }}
                disabled={ttsSpeed <= TTS_SPEED_MIN}
              >
                <Text style={styles.prerollButtonText}>−0.1</Text>
              </TouchableOpacity>
              <Text style={styles.prerollValue}>{ttsSpeed.toFixed(1)} x</Text>
              <TouchableOpacity
                style={styles.prerollButton}
                onPress={() => {
                  const next = Math.min(TTS_SPEED_MAX, Math.round((ttsSpeed + 0.1) * 10) / 10);
                  setTtsSpeed(next);
                  AsyncStorage.setItem(TTS_SPEED_STORAGE_KEY, String(next));
                }}
                disabled={ttsSpeed >= TTS_SPEED_MAX}
              >
                <Text style={styles.prerollButtonText}>+0.1</Text>
              </TouchableOpacity>
            </View>
          </View>
        )}

        {ttsEnabled && (
          <View style={{marginTop: 20}}>
            <Text style={styles.toggleLabel}>Stimme (geraetelokal)</Text>
            <Text style={styles.toggleHint}>
              Eine geklonte Stimme auswaehlen. F5-TTS braucht zwingend eine Referenz —
              ohne Auswahl gilt die in Diagnostic gewaehlte globale Stimme.
            </Text>

            {availableVoices.length === 0 ? (
              <Text style={[styles.toggleHint, {marginTop: 8, textAlign: 'center'}]}>
                Keine geklonten Stimmen vorhanden — unten "Eigene Stimme aufnehmen".
              </Text>
            ) : (
              availableVoices.map(v => (
                <View key={v.name} style={[styles.voiceRow, xttsVoice === v.name && styles.voiceRowActive]}>
                  <TouchableOpacity
                    style={{flex: 1}}
                    onPress={() => selectVoice(v.name)}
                  >
                    <Text style={[styles.voiceRowName, xttsVoice === v.name && styles.voiceRowNameActive]}>
                      {v.name}
                    </Text>
                    <Text style={styles.voiceRowMeta}>{(v.size / 1024).toFixed(0)} KB</Text>
                  </TouchableOpacity>
                  {loadingVoice === v.name && (
                    <ActivityIndicator size="small" color="#0096FF" style={{marginRight: 8}} />
                  )}
                  {xttsVoice === v.name && loadingVoice !== v.name && <Text style={styles.voiceRowCheck}>{'\u2713'}</Text>}
                  <TouchableOpacity onPress={() => deleteVoice(v.name)} style={styles.voiceRowDelete}>
                    <Text style={styles.voiceRowDeleteIcon}>X</Text>
                  </TouchableOpacity>
                </View>
              ))
            )}

            <View style={{flexDirection: 'row', gap: 8, marginTop: 12}}>
              <TouchableOpacity
                style={[styles.connectButton, {flex: 1}]}
                onPress={() => setVoiceCloneVisible(true)}
              >
                <Text style={styles.connectButtonText}>{'\uD83C\uDFA4'} Eigene Stimme aufnehmen</Text>
              </TouchableOpacity>
              <TouchableOpacity
                style={[styles.clearButton, {flex: 0.4, marginTop: 0}]}
                onPress={() => rvs.send('xtts_list_voices' as any, {})}
              >
                <Text style={styles.clearButtonText}>Aktualisieren</Text>
              </TouchableOpacity>
            </View>
          </View>
        )}
      </View>

      </>)}

      {/* === Speicher === */}
      {currentSection === 'storage' && (<>
      <Text style={styles.sectionTitle}>Anhang-Speicher</Text>
      <View style={styles.card}>
        <View style={styles.toggleRow}>
          <View style={styles.toggleInfo}>
            <Text style={styles.toggleLabel}>Auto-Download</Text>
            <Text style={styles.toggleHint}>
              Fehlende Anhaenge beim App-Start automatisch vom Server laden
            </Text>
          </View>
          <Switch
            value={autoDownload}
            onValueChange={(val) => {
              setAutoDownload(val);
              AsyncStorage.setItem('aria_auto_download', String(val));
            }}
            trackColor={{ false: '#2A2A3E', true: '#0096FF' }}
            thumbColor={autoDownload ? '#FFFFFF' : '#666680'}
          />
        </View>

        <View style={{height: 16}} />
        <Text style={styles.toggleLabel}>Lokaler Speicherort</Text>
        <Text style={styles.toggleHint}>
          Hier werden Bilder und Dateien aus dem Chat gespeichert.
          {autoDownload ? ' Fehlende Dateien werden automatisch nachgeladen.' : ' Fehlende Dateien koennen per Tippen geladen werden.'}
        </Text>

        {editingPath ? (
          <View style={{marginTop: 10}}>
            <TextInput
              style={styles.input}
              value={tempPath}
              onChangeText={setTempPath}
              placeholder="z.B. /storage/emulated/0/ARIA/attachments"
              placeholderTextColor="#555570"
              autoCapitalize="none"
            />
            <View style={{flexDirection: 'row', gap: 8}}>
              <TouchableOpacity
                style={[styles.connectButton, {flex: 1}]}
                onPress={() => saveStoragePath(tempPath)}
              >
                <Text style={styles.connectButtonText}>Speichern</Text>
              </TouchableOpacity>
              <TouchableOpacity
                style={[styles.clearButton, {flex: 1, marginTop: 0}]}
                onPress={() => setEditingPath(false)}
              >
                <Text style={styles.clearButtonText}>Abbrechen</Text>
              </TouchableOpacity>
            </View>
          </View>
        ) : (
          <View style={{marginTop: 10}}>
            <Text style={styles.storagePathText} numberOfLines={2}>{storagePath}</Text>
            <Text style={styles.storageSizeText}>{storageSize}</Text>
            <View style={{flexDirection: 'row', gap: 8, marginTop: 8}}>
              <TouchableOpacity
                style={[styles.clearButton, {flex: 1, marginTop: 0}]}
                onPress={showPathPicker}
              >
                <Text style={styles.clearButtonText}>Pfad aendern</Text>
              </TouchableOpacity>
              <TouchableOpacity
                style={[styles.clearButton, {flex: 1, marginTop: 0, backgroundColor: 'rgba(255,59,48,0.15)'}]}
                onPress={clearStorageCache}
              >
                <Text style={[styles.clearButtonText, {color: '#FF3B30'}]}>Cache leeren</Text>
              </TouchableOpacity>
            </View>
          </View>
        )}
      </View>

      {/* === Update-Cache === */}
      <Text style={[styles.sectionTitle, {marginTop: 16}]}>Update-Cache</Text>
      <View style={styles.card}>
        <Text style={styles.toggleHint}>
          Heruntergeladene APK-Dateien fuer App-Updates. Werden automatisch
          beim App-Start und vor jedem neuen Download geloescht — der Button
          ist fuer den Notfall (z.B. wenn ein Download haengen geblieben ist).
        </Text>
        <Text style={[styles.storageSizeText, {marginTop: 8}]}>
          {apkCacheInfo === null ? '...' :
           apkCacheInfo.count === 0 ? 'leer' :
           `${apkCacheInfo.count} APK${apkCacheInfo.count === 1 ? '' : 's'} · ${apkCacheInfo.totalMB.toFixed(1)}MB`}
        </Text>
        <TouchableOpacity
          style={[styles.clearButton, {marginTop: 8, backgroundColor: 'rgba(255,59,48,0.15)'}]}
          onPress={async () => {
            const res = await updateService.cleanupOldApks();
            ToastAndroid.show(
              res.removed === 0
                ? 'Update-Cache war schon leer'
                : `${res.removed} APK${res.removed === 1 ? '' : 's'} geloescht (${res.freedMB.toFixed(1)}MB frei)`,
              ToastAndroid.SHORT,
            );
            const info = await updateService.getApkCacheSize();
            setApkCacheInfo(info);
          }}
        >
          <Text style={[styles.clearButtonText, {color: '#FF3B30'}]}>Update-Cache leeren</Text>
        </TouchableOpacity>
      </View>

      </>)}

      {/* === Logs === */}
      {currentSection === 'protocol' && (<>
      <Text style={styles.sectionTitle}>Protokoll</Text>
      <View style={styles.card}>
        {/* Tab-Umschalter */}
        <View style={styles.tabRow}>
          <TouchableOpacity
            style={[styles.tab, logTab === 'live' && styles.tabActive]}
            onPress={() => setLogTab('live')}
          >
            <Text style={[styles.tabText, logTab === 'live' && styles.tabTextActive]}>
              Live Logs
            </Text>
          </TouchableOpacity>
          <TouchableOpacity
            style={[styles.tab, logTab === 'events' && styles.tabActive]}
            onPress={() => setLogTab('events')}
          >
            <Text style={[styles.tabText, logTab === 'events' && styles.tabTextActive]}>
              Events
            </Text>
          </TouchableOpacity>
        </View>

        {/* Log-Inhalt */}
        <View style={styles.logContainer}>
          {logTab === 'live' ? (
            logs.length > 0 ? (
              logs.slice(-50).map(log => (
                <View key={log.id} style={styles.logEntry}>
                  <Text style={styles.logTime}>{formatTime(log.timestamp)}</Text>
                  <Text
                    style={[
                      styles.logSource,
                      { color: SOURCE_COLORS[log.source] || SOURCE_COLORS.default },
                    ]}
                  >
                    [{log.source}]
                  </Text>
                  <Text
                    style={[
                      styles.logMessage,
                      log.level === 'error' && styles.logError,
                      log.level === 'warn' && styles.logWarn,
                    ]}
                    numberOfLines={2}
                  >
                    {log.message}
                  </Text>
                </View>
              ))
            ) : (
              <Text style={styles.emptyLog}>Noch keine Logs empfangen</Text>
            )
          ) : (
            events.length > 0 ? (
              events.slice(-30).map(event => (
                <View key={event.id} style={styles.eventEntry}>
                  <Text style={styles.eventTime}>{formatTime(event.timestamp)}</Text>
                  <Text style={styles.eventTitle}>{event.title}</Text>
                  <Text style={styles.eventDescription}>{event.description}</Text>
                </View>
              ))
            ) : (
              <Text style={styles.emptyLog}>Noch keine Events empfangen</Text>
            )
          )}
        </View>

        {/* Log-Aktionen */}
        <TouchableOpacity
          style={styles.clearButton}
          onPress={() => {
            if (logTab === 'live') setLogs([]);
            else setEvents([]);
          }}
        >
          <Text style={styles.clearButtonText}>Protokoll l\u00F6schen</Text>
        </TouchableOpacity>
      </View>
      </>)}

      {/* === About === */}
      {currentSection === 'about' && (<>
      <Text style={styles.sectionTitle}>{'\u00DC'}ber</Text>
      <View style={styles.card}>
        <Text style={styles.aboutTitle}>ARIA Cockpit</Text>
        <Text style={styles.aboutVersion}>Version {require('../../package.json').version}</Text>
        <Text style={styles.aboutInfo}>
          Stefans Kommandozentrale f{'\u00FC'}r ARIA.{'\n'}
          Gebaut mit React Native + TypeScript.
        </Text>
        <TouchableOpacity
          style={[styles.connectButton, {marginTop: 12}]}
          onPress={() => {
            const updateService = require('../services/updater').default;
            updateService.checkForUpdate();
            Alert.alert('Update-Check', 'Pruefe auf neue Version...');
          }}
        >
          <Text style={styles.connectButtonText}>Auf Updates pr{'\u00FC'}fen</Text>
        </TouchableOpacity>
      </View>
      </>)}

      {/* Platz am Ende */}
      <View style={styles.bottomSpacer} />
    </ScrollView>
    </>
  );
};

// --- Styles ---

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#0D0D1A',
  },
  content: {
    padding: 16,
  },
  sectionTitle: {
    color: '#8888AA',
    fontSize: 13,
    fontWeight: '700',
    textTransform: 'uppercase',
    letterSpacing: 1,
    marginTop: 20,
    marginBottom: 8,
    marginLeft: 4,
  },
  menuItem: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: '#1E1E2E',
    borderRadius: 10,
    paddingVertical: 14,
    paddingHorizontal: 14,
    marginBottom: 8,
  },
  menuItemIcon: {
    fontSize: 22,
    marginRight: 14,
    width: 28,
    textAlign: 'center',
  },
  menuItemTextWrap: {
    flex: 1,
  },
  menuItemLabel: {
    color: '#FFFFFF',
    fontSize: 16,
    fontWeight: '600',
  },
  menuItemDesc: {
    color: '#8888AA',
    fontSize: 12,
    marginTop: 2,
  },
  menuItemChevron: {
    color: '#8888AA',
    fontSize: 24,
    fontWeight: '300',
    marginLeft: 8,
  },
  subScreenHeader: {
    flexDirection: 'row',
    alignItems: 'center',
    paddingVertical: 8,
    marginBottom: 8,
  },
  subScreenBack: {
    color: '#0096FF',
    fontSize: 32,
    fontWeight: '300',
    marginRight: 12,
    lineHeight: 36,
  },
  subScreenTitle: {
    color: '#FFFFFF',
    fontSize: 20,
    fontWeight: '700',
  },
  card: {
    backgroundColor: '#12122A',
    borderRadius: 14,
    padding: 16,
    borderWidth: 1,
    borderColor: '#1E1E2E',
  },

  // Verbindungsstatus
  statusRow: {
    flexDirection: 'row',
    alignItems: 'center',
    marginBottom: 16,
  },
  statusDot: {
    width: 10,
    height: 10,
    borderRadius: 5,
    marginRight: 10,
  },
  statusLabel: {
    color: '#FFFFFF',
    fontSize: 16,
    fontWeight: '600',
    flex: 1,
  },
  disconnectButton: {
    paddingHorizontal: 12,
    paddingVertical: 6,
    borderRadius: 6,
    backgroundColor: 'rgba(255, 59, 48, 0.2)',
  },
  disconnectText: {
    color: '#FF3B30',
    fontSize: 13,
    fontWeight: '600',
  },

  // QR-Button
  qrButton: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: '#1E1E2E',
    borderRadius: 10,
    padding: 14,
    marginBottom: 16,
  },
  qrIcon: {
    fontSize: 22,
    marginRight: 10,
  },
  qrText: {
    color: '#FFFFFF',
    fontSize: 15,
    fontWeight: '500',
  },

  // Eingabefelder
  inputLabel: {
    color: '#8888AA',
    fontSize: 12,
    marginBottom: 4,
    marginLeft: 2,
  },
  input: {
    backgroundColor: '#1E1E2E',
    borderRadius: 8,
    paddingHorizontal: 14,
    paddingVertical: 10,
    color: '#FFFFFF',
    fontSize: 15,
    marginBottom: 12,
    borderWidth: 1,
    borderColor: '#2A2A3E',
  },
  connectButton: {
    backgroundColor: '#0096FF',
    borderRadius: 10,
    padding: 14,
    alignItems: 'center',
    marginTop: 4,
  },
  connectButtonText: {
    color: '#FFFFFF',
    fontSize: 16,
    fontWeight: '700',
  },

  // Toggle
  toggleRow: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
  },
  toggleInfo: {
    flex: 1,
    marginRight: 12,
  },
  toggleLabel: {
    color: '#FFFFFF',
    fontSize: 15,
    fontWeight: '500',
  },
  toggleHint: {
    color: '#666680',
    fontSize: 12,
    marginTop: 2,
  },

  // XTTS Voice List
  voiceRow: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: '#1E1E2E',
    borderRadius: 8,
    padding: 10,
    marginTop: 6,
    borderWidth: 1,
    borderColor: 'transparent',
  },
  voiceRowActive: {
    borderColor: '#0096FF',
    backgroundColor: '#0D1A2E',
  },
  voiceRowName: {
    color: '#CCCCDD',
    fontSize: 14,
    fontWeight: '500',
  },
  voiceRowNameActive: {
    color: '#FFFFFF',
  },
  voiceRowMeta: {
    color: '#666680',
    fontSize: 11,
    marginTop: 2,
  },
  voiceRowCheck: {
    color: '#34C759',
    fontSize: 16,
    fontWeight: '700',
    marginHorizontal: 6,
  },
  voiceRowDelete: {
    width: 28,
    height: 28,
    borderRadius: 14,
    backgroundColor: 'rgba(255,59,48,0.2)',
    alignItems: 'center',
    justifyContent: 'center',
    marginLeft: 4,
  },
  voiceRowDeleteIcon: {
    color: '#FF3B30',
    fontSize: 12,
    fontWeight: '700',
  },

  // Stimmen
  voiceBtn: {
    flex: 1,
    padding: 12,
    borderRadius: 10,
    backgroundColor: '#1E1E2E',
    alignItems: 'center',
    borderWidth: 2,
    borderColor: 'transparent',
  },
  voiceBtnActive: {
    borderColor: '#0096FF',
    backgroundColor: '#0D1A2E',
  },
  voiceBtnIcon: {
    fontSize: 28,
    marginBottom: 4,
  },
  voiceBtnText: {
    color: '#8888AA',
    fontSize: 14,
    fontWeight: '600',
  },
  voiceBtnTextActive: {
    color: '#FFFFFF',
  },
  voiceBtnHint: {
    color: '#555570',
    fontSize: 11,
    marginTop: 2,
  },

  // Speicher
  storagePathText: {
    color: '#0096FF',
    fontSize: 12,
    fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
  },
  storageSizeText: {
    color: '#8888AA',
    fontSize: 12,
    marginTop: 4,
  },

  // Logs
  tabRow: {
    flexDirection: 'row',
    marginBottom: 12,
    borderRadius: 8,
    backgroundColor: '#1E1E2E',
    overflow: 'hidden',
  },
  tab: {
    flex: 1,
    paddingVertical: 10,
    alignItems: 'center',
  },
  tabActive: {
    backgroundColor: '#0096FF',
  },
  tabText: {
    color: '#666680',
    fontSize: 13,
    fontWeight: '600',
  },
  tabTextActive: {
    color: '#FFFFFF',
  },
  connLogScroll: {
    maxHeight: 200,
    backgroundColor: '#0A0A18',
    borderRadius: 8,
    padding: 10,
  },
  logContainer: {
    maxHeight: 300,
    backgroundColor: '#0A0A18',
    borderRadius: 8,
    padding: 10,
  },
  logEntry: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    marginBottom: 4,
  },
  logTime: {
    color: '#555570',
    fontSize: 11,
    fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
    marginRight: 6,
  },
  logSource: {
    fontSize: 11,
    fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
    fontWeight: '700',
    marginRight: 6,
  },
  logMessage: {
    color: '#CCCCDD',
    fontSize: 11,
    fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
    flex: 1,
  },
  logError: {
    color: '#FF3B30',
  },
  logWarn: {
    color: '#FFD60A',
  },
  emptyLog: {
    color: '#555570',
    fontSize: 13,
    textAlign: 'center',
    padding: 20,
  },
  eventEntry: {
    marginBottom: 10,
    paddingBottom: 10,
    borderBottomWidth: 1,
    borderBottomColor: '#1E1E2E',
  },
  eventTime: {
    color: '#555570',
    fontSize: 11,
  },
  eventTitle: {
    color: '#FFFFFF',
    fontSize: 14,
    fontWeight: '600',
    marginTop: 2,
  },
  eventDescription: {
    color: '#8888AA',
    fontSize: 13,
    marginTop: 2,
  },
  clearButton: {
    marginTop: 10,
    padding: 10,
    alignItems: 'center',
    borderRadius: 8,
    backgroundColor: '#1E1E2E',
  },
  clearButtonText: {
    color: '#666680',
    fontSize: 13,
    fontWeight: '500',
  },

  // About
  aboutTitle: {
    color: '#FFFFFF',
    fontSize: 18,
    fontWeight: '700',
  },
  aboutVersion: {
    color: '#0096FF',
    fontSize: 13,
    marginTop: 2,
  },
  aboutInfo: {
    color: '#666680',
    fontSize: 13,
    marginTop: 8,
    lineHeight: 20,
  },

  bottomSpacer: {
    height: 40,
  },

  prerollRow: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    marginTop: 12,
    gap: 16,
  },
  prerollButton: {
    backgroundColor: '#2A2A3E',
    paddingHorizontal: 18,
    paddingVertical: 10,
    borderRadius: 8,
    minWidth: 72,
    alignItems: 'center',
  },
  prerollButtonText: {
    color: '#FFFFFF',
    fontSize: 16,
    fontWeight: '600',
  },
  prerollValue: {
    color: '#FFFFFF',
    fontSize: 20,
    fontWeight: '700',
    minWidth: 80,
    textAlign: 'center',
  },

  infoBtn: {
    width: 22,
    height: 22,
    borderRadius: 11,
    borderWidth: 1.5,
    borderColor: '#0096FF',
    alignItems: 'center',
    justifyContent: 'center',
  },
  infoBtnText: {
    color: '#0096FF',
    fontSize: 13,
    fontWeight: '700',
    fontStyle: 'italic',
    lineHeight: 16,
  },
  modalOverlay: {
    flex: 1,
    backgroundColor: 'rgba(0,0,0,0.7)',
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
  },
  modalCard: {
    backgroundColor: '#1E1E2E',
    borderRadius: 14,
    padding: 20,
    maxWidth: 460,
    width: '100%',
  },
  modalTitle: {
    color: '#FFFFFF',
    fontSize: 18,
    fontWeight: '700',
    marginBottom: 12,
  },
  modalText: {
    color: '#E0E0F0',
    fontSize: 14,
    lineHeight: 20,
  },

  keywordChip: {
    backgroundColor: '#1E1E2E',
    borderWidth: 1,
    borderColor: '#2A2A3E',
    paddingHorizontal: 12,
    paddingVertical: 6,
    borderRadius: 14,
  },
  keywordChipActive: {
    backgroundColor: '#0096FF',
    borderColor: '#0096FF',
  },
  keywordChipText: {
    color: '#8888AA',
    fontSize: 13,
    fontWeight: '500',
  },
  keywordChipTextActive: {
    color: '#FFFFFF',
    fontWeight: '700',
  },
});

export default SettingsScreen;
