// ── Lightweight i18n ─────────────────────────────────────────────────────────
// English is the source language (keys = the exact English UI text). Switching
// language persists the choice and reloads, so translations are applied once to the
// freshly-rendered English DOM (no fragile reverse-translation / re-render tracking).
//
// Coverage v1: the static UI chrome (nav, section titles/subtitles, common
// buttons/labels). Add more by adding "English": "translation" pairs below, or call
// window.t('English') for JS-generated strings. Dynamic lists can be translated by
// calling window.applyI18n(container) after rendering.

const I18N_LANGS = { en: 'English', de: 'Deutsch' };

const I18N_DICT = {
  de: {
    // Brand / sidebar groups
    'Voice Creator': 'Voice Creator',
    'Clone · Design · Deploy': 'Klonen · Entwerfen · Bereitstellen',
    'Voices': 'Stimmen', 'Setup': 'Einrichtung', 'Tags': 'Tags',
    // Sidebar nav
    'My Voices': 'Meine Stimmen', 'All voices': 'Alle Stimmen', 'Cloned': 'Geklont',
    'Designed': 'Entworfen', 'Favorites': 'Favoriten', 'Hidden': 'Ausgeblendet',
    'Library tools': 'Bibliothekswerkzeuge',
    'Clone a Voice': 'Stimme klonen', 'Design a Voice': 'Stimme entwerfen',
    'Get Voices Online': 'Stimmen online holen', 'Try It Out': 'Ausprobieren',
    'Read Aloud': 'Vorlesen',
    'Script Rehearser': 'Skript-Probe', 'Library': 'Bibliothek', 'Cast': 'Besetzung',
    'Stage': 'Bühne', 'Summary': 'Zusammenfassung', 'Import / Export': 'Import / Export',
    'Conversation': 'Unterhaltung', 'Benchmark': 'Benchmark', 'Engines': 'Engines',
    'Language Models': 'Sprachmodelle', 'Speech to Text': 'Sprache-zu-Text',
    'Text to Speech': 'Text-zu-Sprache', 'App Routing': 'App-Routing',
    'Connect Apps': 'Apps verbinden', 'Settings': 'Einstellungen',
    // Section titles
    'Conversation Playground': 'Unterhaltungs-Spielplatz',
    // Section subtitles
    'Pick a voice on the left, edit on the right.': 'Wähle links eine Stimme, bearbeite sie rechts.',
    'Capture 3–20 seconds of clean speech, trim it, name it, then save it as a reusable voice clone.':
      'Nimm 3–20 Sekunden saubere Sprache auf, schneide sie zu, benenne sie und speichere sie als wiederverwendbaren Stimmklon.',
    'Describe a voice in words and let the AI create it. No recording needed.':
      'Beschreibe eine Stimme in Worten und lass sie von der KI erstellen. Keine Aufnahme nötig.',
    'Browse public voice clip sources, preview direct audio files, and import voices from the web.':
      'Durchsuche öffentliche Stimm-Quellen, höre Audiodateien vorab an und importiere Stimmen aus dem Web.',
    'Generate speech from text using any backend and voice. Also transcribe audio and re-speak it.':
      'Erzeuge Sprache aus Text mit beliebigem Backend und Stimme. Transkribiere Audio und sprich es neu ein.',
    'Upload a script, cast characters to TTS voices or your own mic, then rehearse scene by scene.':
      'Lade ein Skript hoch, besetze Figuren mit TTS-Stimmen oder deinem Mikrofon und probe Szene für Szene.',
    'Import a PDF or text document, pick a voice and speed, then have it read to you while the word being spoken is highlighted.':
      'Importiere ein PDF- oder Textdokument, wähle Stimme und Tempo und lass es dir vorlesen, während das gerade gesprochene Wort hervorgehoben wird.',
    // Read Aloud UI
    'My books': 'Meine Bücher', 'Voice consistency': 'Stimmkonstanz',
    'Normalise loudness': 'Lautstärke angleichen', 'Export MP3': 'MP3 exportieren',
    'Select range': 'Bereich wählen', 'Synthesise': 'Synthetisieren',
    'Tone / style': 'Ton / Stil', 'Temperature': 'Temperatur', 'Speed': 'Tempo',
    'Saved documents with their synthesised audio — reopen to continue.':
      'Gespeicherte Dokumente mit ihrem synthetisierten Audio — zum Fortsetzen erneut öffnen.',
    // Common buttons / labels
    'Save changes': 'Änderungen speichern', 'Save to library': 'In Bibliothek speichern',
    'Save to Voice Library': 'In Stimmbibliothek speichern', 'Delete voice': 'Stimme löschen',
    'Cancel': 'Abbrechen', 'Refresh': 'Aktualisieren', 'Delete': 'Löschen', 'Save': 'Speichern',
    'Back': 'Zurück', 'Apply →': 'Anwenden →', 'Browse': 'Durchsuchen', 'Download': 'Herunterladen',
    'Record': 'Aufnehmen', 'Stop': 'Stopp', 'Play': 'Abspielen', 'Play selection': 'Auswahl abspielen',
    'Check level': 'Pegel prüfen', 'Stop monitor': 'Monitor stoppen', 'Auto trim': 'Auto-Zuschnitt',
    'Auto-transcribe': 'Auto-Transkription', 'Active': 'Aktiv', 'copy ID': 'ID kopieren',
    'edit ID': 'ID bearbeiten', 'New voice': 'Neue Stimme', 'All languages': 'Alle Sprachen',
    'All genders': 'Alle Geschlechter', 'Microphone': 'Mikrofon', 'Upload file': 'Datei hochladen',
    'Sort': 'Sortieren', 'Cards': 'Karten', 'List': 'Liste', 'Develop': 'Ausarbeiten',
    'Match local': 'Lokal zuordnen', 'Match online': 'Online zuordnen', 'Design all': 'Alle entwerfen',
    'I play this': 'Ich spiele das', 'Save to library': 'In Bibliothek speichern',
    'Open rehearsal': 'Probe öffnen', 'Fetch voices': 'Stimmen abrufen',
    'Name your voice': 'Benenne deine Stimme', 'Reference transcript': 'Referenz-Transkript',
    'Preview': 'Vorschau', 'Trim your sample': 'Probe zuschneiden', 'Language': 'Sprache',
    'Gender': 'Geschlecht', 'Voice': 'Stimme', 'Tags': 'Tags', 'Speaking style · voice-design prompt': 'Sprechstil · Voice-Design-Prompt',
    // Common placeholders
    'Search voices…': 'Stimmen suchen…', 'Search voices...': 'Stimmen suchen...',
    'Filter name or tag…': 'Name oder Tag filtern…',
  },
};

let _appLang = 'en';
try { _appLang = localStorage.getItem('app-lang') || 'en'; } catch (_) {}
window.__APP_LANG__ = _appLang;

// Translate a single source string (for JS-generated UI).
window.t = function (s) {
  if (_appLang === 'en' || s == null) return s;
  const d = I18N_DICT[_appLang];
  return (d && d[String(s).trim()] != null) ? d[String(s).trim()] : s;
};

const _I18N_SKIP = new Set(['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'CODE', 'PRE', 'OPTION']);

// Translate visible text nodes + common attributes within `root` (default: whole doc).
window.applyI18n = function (root) {
  if (_appLang === 'en') return;
  const dict = I18N_DICT[_appLang]; if (!dict) return;
  root = root || document.body; if (!root) return;
  const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
    acceptNode(n) {
      if (!n.nodeValue || !n.nodeValue.trim()) return NodeFilter.FILTER_REJECT;
      const p = n.parentNode;
      if (p && _I18N_SKIP.has(p.nodeName)) return NodeFilter.FILTER_REJECT;
      return NodeFilter.FILTER_ACCEPT;
    },
  });
  const nodes = []; while (walker.nextNode()) nodes.push(walker.currentNode);
  for (const n of nodes) {
    const key = n.nodeValue.trim();
    if (dict[key] != null) n.nodeValue = n.nodeValue.replace(key, dict[key]);
  }
  root.querySelectorAll('[placeholder],[title],[aria-label]').forEach(el => {
    ['placeholder', 'title', 'aria-label'].forEach(a => {
      const v = el.getAttribute(a);
      if (v && dict[v.trim()] != null) el.setAttribute(a, dict[v.trim()]);
    });
  });
};

// Language change → persist + reload (translations re-apply to fresh English DOM).
window.setAppLang = function (lang) {
  if (!I18N_LANGS[lang]) return;
  try { localStorage.setItem('app-lang', lang); } catch (_) {}
  location.reload();
};

// Flag of a language code (flag-icons classes; English → GB).
function _langFlag(code) { return code === 'en' ? 'gb' : code; }

// Inject a flag toggle next to the "Voice Creator" headline. Clicking cycles to
// the next language (a simple toggle while there are two).
window.initLangPicker = function () {
  const brand = document.querySelector('.sidebar-brand');
  const head = brand && brand.querySelector('h1');
  if (!head || document.getElementById('app-lang-toggle')) return;
  const codes = Object.keys(I18N_LANGS);
  const btn = document.createElement('button');
  btn.id = 'app-lang-toggle';
  btn.className = 'app-lang-toggle';
  btn.type = 'button';
  const nextOf = () => codes[(codes.indexOf(_appLang) + 1) % codes.length];
  const render = () => {
    btn.innerHTML = `<span class="fi fi-${_langFlag(_appLang)}"></span>`;
    const label = 'Language: ' + I18N_LANGS[_appLang] + ' — switch to ' + I18N_LANGS[nextOf()];
    btn.title = label; btn.setAttribute('aria-label', label);
  };
  render();
  btn.addEventListener('click', () => window.setAppLang(nextOf()));
  head.appendChild(btn);
};
