(() => {
  'use strict';
  if (window.__APU_DESIGN_I18N_V55__) return;
  window.__APU_DESIGN_I18N_V55__ = true;

  const THEME_KEY = 'apu-ui-theme-v5.5';
  const LANGUAGE_KEY = 'apu-ui-language-v5.5';
  const LANGUAGES = {
    id: { name: 'Indonesia', short: 'ID' },
    en: { name: 'English', short: 'EN' },
    ms: { name: 'Melayu', short: 'MS' },
    de: { name: 'Deutsch', short: 'DE' },
    vi: { name: 'Tiếng Việt', short: 'VI' },
    zh: { name: '中文', short: '中文' },
    ja: { name: '日本語', short: '日本' }
  };

  const UI = {
    id: { theme: 'Ganti mode warna', light: 'Mode terang aktif', dark: 'Mode gelap aktif', language: 'Pilih bahasa', changed: 'Bahasa diubah ke Indonesia' },
    en: { theme: 'Change color mode', light: 'Light mode enabled', dark: 'Dark mode enabled', language: 'Choose language', changed: 'Language changed to English' },
    ms: { theme: 'Tukar mod warna', light: 'Mod cerah diaktifkan', dark: 'Mod gelap diaktifkan', language: 'Pilih bahasa', changed: 'Bahasa ditukar kepada Melayu' },
    de: { theme: 'Farbmodus wechseln', light: 'Heller Modus aktiviert', dark: 'Dunkler Modus aktiviert', language: 'Sprache wählen', changed: 'Sprache auf Deutsch geändert' },
    vi: { theme: 'Đổi chế độ màu', light: 'Đã bật chế độ sáng', dark: 'Đã bật chế độ tối', language: 'Chọn ngôn ngữ', changed: 'Đã đổi ngôn ngữ sang Tiếng Việt' },
    zh: { theme: '切换颜色模式', light: '已启用浅色模式', dark: '已启用深色模式', language: '选择语言', changed: '语言已切换为中文' },
    ja: { theme: 'カラーモードを変更', light: 'ライトモードを有効化', dark: 'ダークモードを有効化', language: '言語を選択', changed: '言語を日本語に変更しました' }
  };

  const PHRASES = {
    'Overview': ['Ikhtisar','Overview','Gambaran keseluruhan','Übersicht','Tổng quan','概览','概要'],
    'Dashboard': ['Dasbor','Dashboard','Papan pemuka','Dashboard','Bảng điều khiển','仪表板','ダッシュボード'],
    'Dataset': ['Kumpulan Data','Dataset','Set data','Datensatz','Tập dữ liệu','数据集','データセット'],
    'Model': ['Model','Model','Model','Modell','Mô hình','模型','モデル'],
    'Models': ['Model','Models','Model','Modelle','Mô hình','模型','モデル'],
    'Results': ['Hasil','Results','Keputusan','Ergebnisse','Kết quả','结果','結果'],
    'Analysis': ['Analisis','Analysis','Analisis','Analyse','Phân tích','分析','分析'],
    'Failure Analysis': ['Analisis Kegagalan','Failure Analysis','Analisis Kegagalan','Fehleranalyse','Phân tích lỗi','失败分析','失敗分析'],
    'Limitations': ['Keterbatasan','Limitations','Batasan','Einschränkungen','Hạn chế','局限性','制限事項'],
    'Source Code': ['Kode Sumber','Source Code','Kod Sumber','Quellcode','Mã nguồn','源代码','ソースコード'],
    'Technical Report': ['Laporan Teknis','Technical Report','Laporan Teknikal','Technischer Bericht','Báo cáo kỹ thuật','技术报告','技術レポート'],
    'Reports': ['Laporan','Reports','Laporan','Berichte','Báo cáo','报告','レポート'],
    'Report': ['Laporan','Report','Laporan','Bericht','Báo cáo','报告','レポート'],
    'Settings': ['Pengaturan','Settings','Tetapan','Einstellungen','Cài đặt','设置','設定'],
    'Search': ['Cari','Search','Cari','Suchen','Tìm kiếm','搜索','検索'],
    'Home': ['Beranda','Home','Laman Utama','Startseite','Trang chủ','首页','ホーム'],
    'Projects': ['Proyek','Projects','Projek','Projekte','Dự án','项目','プロジェクト'],
    'Project': ['Proyek','Project','Projek','Projekt','Dự án','项目','プロジェクト'],
    'Research': ['Riset','Research','Penyelidikan','Forschung','Nghiên cứu','研究','研究'],
    'Certificates': ['Sertifikat','Certificates','Sijil','Zertifikate','Chứng chỉ','证书','証明書'],
    'Admission': ['Penerimaan','Admission','Kemasukan','Zulassung','Tuyển sinh','招生','入学'],
    'Documents': ['Dokumen','Documents','Dokumen','Dokumente','Tài liệu','文档','ドキュメント'],
    'Contact': ['Kontak','Contact','Hubungi','Kontakt','Liên hệ','联系','お問い合わせ'],
    'Support': ['Dukungan','Support','Sokongan','Support','Hỗ trợ','支持','サポート'],
    'Resume': ['Resume','Resume','Resume','Lebenslauf','Hồ sơ','简历','履歴書'],
    'Security': ['Keamanan','Security','Keselamatan','Sicherheit','Bảo mật','安全','セキュリティ'],
    'Governance': ['Tata Kelola','Governance','Tadbir Urus','Governance','Quản trị','治理','ガバナンス'],
    'Cloud Compare': ['Perbandingan Cloud','Cloud Compare','Perbandingan Awan','Cloud-Vergleich','So sánh đám mây','云对比','クラウド比較'],
    'Blueprints': ['Cetak Biru','Blueprints','Pelan Tindakan','Blaupausen','Bản thiết kế','蓝图','ブループリント'],
    'Agents': ['Agen','Agents','Ejen','Agenten','Tác nhân','智能体','エージェント'],
    'Predict': ['Prediksi','Predict','Ramalan','Vorhersage','Dự đoán','预测','予測'],
    'Recommendations': ['Rekomendasi','Recommendations','Cadangan','Empfehlungen','Đề xuất','建议','推奨事項'],
    'Students': ['Siswa','Students','Pelajar','Studierende','Sinh viên','学生','学生'],
    'Fairness': ['Keadilan','Fairness','Keadilan','Fairness','Công bằng','公平性','公平性'],
    'Tickets': ['Tiket','Tickets','Tiket','Tickets','Phiếu hỗ trợ','工单','チケット'],
    'Incidents': ['Insiden','Incidents','Insiden','Vorfälle','Sự cố','事件','インシデント'],
    'Timeline': ['Linimasa','Timeline','Garis Masa','Zeitleiste','Dòng thời gian','时间线','タイムライン'],
    'Analytics': ['Analitik','Analytics','Analitik','Analytik','Phân tích','分析','分析'],
    'Campaigns': ['Kampanye','Campaigns','Kempen','Kampagnen','Chiến dịch','活动','キャンペーン'],
    'Create': ['Buat','Create','Cipta','Erstellen','Tạo','创建','作成'],
    'History': ['Riwayat','History','Sejarah','Verlauf','Lịch sử','历史','履歴'],
    'Calculator': ['Kalkulator','Calculator','Kalkulator','Rechner','Máy tính','计算器','計算機'],
    'Troubleshoot': ['Pemecahan Masalah','Troubleshoot','Penyelesaian Masalah','Fehlerbehebung','Khắc phục sự cố','故障排除','トラブルシューティング'],
    'Tutorial': ['Tutorial','Tutorial','Tutorial','Tutorial','Hướng dẫn','教程','チュートリアル'],
    'Segmentation': ['Segmentasi','Segmentation','Segmentasi','Segmentierung','Phân đoạn','分段','セグメンテーション'],
    'Feedback': ['Umpan Balik','Feedback','Maklum Balas','Feedback','Phản hồi','反馈','フィードバック'],
    'New Feedback': ['Umpan Balik Baru','New Feedback','Maklum Balas Baharu','Neues Feedback','Phản hồi mới','新反馈','新しいフィードバック'],
    'Keywords': ['Kata Kunci','Keywords','Kata Kunci','Schlüsselwörter','Từ khóa','关键词','キーワード'],
    'Topics': ['Topik','Topics','Topik','Themen','Chủ đề','主题','トピック'],
    'Categories': ['Kategori','Categories','Kategori','Kategorien','Danh mục','类别','カテゴリー'],
    'Costs': ['Biaya','Costs','Kos','Kosten','Chi phí','费用','費用'],
    'Housing': ['Perumahan','Housing','Perumahan','Wohnen','Nhà ở','住房','住宅'],
    'Simulator': ['Simulator','Simulator','Simulator','Simulator','Mô phỏng','模拟器','シミュレーター'],
    'Methodology': ['Metodologi','Methodology','Metodologi','Methodik','Phương pháp','方法论','方法論'],
    'Save': ['Simpan','Save','Simpan','Speichern','Lưu','保存','保存'],
    'Cancel': ['Batal','Cancel','Batal','Abbrechen','Hủy','取消','キャンセル'],
    'Delete': ['Hapus','Delete','Padam','Löschen','Xóa','删除','削除'],
    'Edit': ['Edit','Edit','Sunting','Bearbeiten','Chỉnh sửa','编辑','編集'],
    'Update': ['Perbarui','Update','Kemas Kini','Aktualisieren','Cập nhật','更新','更新'],
    'Add': ['Tambah','Add','Tambah','Hinzufügen','Thêm','添加','追加'],
    'Download': ['Unduh','Download','Muat Turun','Herunterladen','Tải xuống','下载','ダウンロード'],
    'Upload': ['Unggah','Upload','Muat Naik','Hochladen','Tải lên','上传','アップロード'],
    'Back': ['Kembali','Back','Kembali','Zurück','Quay lại','返回','戻る'],
    'Next': ['Berikutnya','Next','Seterusnya','Weiter','Tiếp theo','下一步','次へ'],
    'Previous': ['Sebelumnya','Previous','Sebelumnya','Zurück','Trước','上一步','前へ'],
    'View Details': ['Lihat Detail','View Details','Lihat Butiran','Details ansehen','Xem chi tiết','查看详情','詳細を見る'],
    'Loading...': ['Memuat...','Loading...','Memuatkan...','Wird geladen...','Đang tải...','加载中...','読み込み中...'],
    'No data available': ['Tidak ada data','No data available','Tiada data','Keine Daten verfügbar','Không có dữ liệu','暂无数据','データがありません'],
    'Language': ['Bahasa','Language','Bahasa','Sprache','Ngôn ngữ','语言','言語'],
    'Theme': ['Tema','Theme','Tema','Design','Giao diện','主题','テーマ']
  };

  const languageOrder = ['id','en','ms','de','vi','zh','ja'];
  const indexByLanguage = Object.fromEntries(languageOrder.map((lang, index) => [lang, index]));
  const sourceToCanonical = new Map();
  for (const [canonical, translations] of Object.entries(PHRASES)) {
    sourceToCanonical.set(canonical.toLocaleLowerCase(), canonical);
    translations.forEach(value => sourceToCanonical.set(value.toLocaleLowerCase(), canonical));
  }

  const root = document.documentElement;
  const originalText = new WeakMap();
  const originalAttrs = new WeakMap();
  let currentLanguage = root.dataset.apuLanguage || 'en';
  let observer = null;
  let translationQueued = false;
  let toastTimer = 0;

  const normalize = value => value.replace(/\s+/g, ' ').trim();
  const translateValue = (value, language) => {
    const clean = normalize(value);
    const canonical = sourceToCanonical.get(clean.toLocaleLowerCase());
    if (!canonical) return value;
    const translated = PHRASES[canonical][indexByLanguage[language] ?? 1];
    return value.replace(clean, translated);
  };

  function translateTree(container = document.body) {
    if (!container || currentLanguage === 'en' && !document.documentElement.dataset.apuTranslatedOnce) {
      document.documentElement.dataset.apuTranslatedOnce = 'true';
    }

    const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT, {
      acceptNode(node) {
        const parent = node.parentElement;
        if (!parent || parent.closest('#apu-ui-dock-v55, #apu-ui-toast-v55, script, style, code, pre, textarea, [contenteditable="true"]')) return NodeFilter.FILTER_REJECT;
        const text = normalize(node.nodeValue || '');
        if (!text || text.length > 80) return NodeFilter.FILTER_REJECT;
        return sourceToCanonical.has(text.toLocaleLowerCase()) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
      }
    });

    const nodes = [];
    while (walker.nextNode()) nodes.push(walker.currentNode);
    for (const node of nodes) {
      if (!originalText.has(node)) originalText.set(node, node.nodeValue);
      const original = originalText.get(node);
      node.nodeValue = translateValue(original, currentLanguage);
    }

    const elements = container.querySelectorAll ? container.querySelectorAll('[placeholder],[title],[aria-label]') : [];
    for (const element of elements) {
      if (element.closest('#apu-ui-dock-v55, #apu-ui-toast-v55')) continue;
      if (!originalAttrs.has(element)) originalAttrs.set(element, {});
      const stored = originalAttrs.get(element);
      for (const attr of ['placeholder','title','aria-label']) {
        if (!element.hasAttribute(attr)) continue;
        if (!(attr in stored)) stored[attr] = element.getAttribute(attr);
        const original = stored[attr];
        if (original && normalize(original).length <= 80) element.setAttribute(attr, translateValue(original, currentLanguage));
      }
    }
  }

  function queueTranslation(target) {
    if (translationQueued) return;
    translationQueued = true;
    requestAnimationFrame(() => {
      translationQueued = false;
      translateTree(target && target.nodeType === 1 ? target : document.body);
    });
  }

  function setTheme(theme, announce = false) {
    const resolved = theme === 'dark' ? 'dark' : 'light';
    root.dataset.apuTheme = resolved;
    root.style.colorScheme = resolved;
    try { localStorage.setItem(THEME_KEY, resolved); } catch (_) {}
    const meta = document.querySelector('meta[name="theme-color"]') || document.head.appendChild(Object.assign(document.createElement('meta'), { name: 'theme-color' }));
    meta.content = resolved === 'dark' ? '#101010' : '#f7f7f7';
    updateDock();
    if (announce) showToast(UI[currentLanguage][resolved]);
    window.dispatchEvent(new CustomEvent('apu:themechange', { detail: { theme: resolved } }));
  }

  function setLanguage(language, announce = false) {
    if (!LANGUAGES[language]) language = 'en';
    currentLanguage = language;
    root.dataset.apuLanguage = language;
    root.lang = language;
    try { localStorage.setItem(LANGUAGE_KEY, language); } catch (_) {}
    updateDock();
    translateTree(document.body);
    document.title = document.title;
    if (announce) showToast(UI[language].changed);
    window.dispatchEvent(new CustomEvent('apu:languagechange', { detail: { language } }));
  }

  function iconForTheme(theme) {
    return theme === 'dark'
      ? '<svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M12 3v2m0 14v2M3 12h2m14 0h2M5.64 5.64l1.42 1.42m9.88 9.88 1.42 1.42m0-12.72-1.42 1.42M7.06 16.94l-1.42 1.42M16.5 12a4.5 4.5 0 1 1-9 0 4.5 4.5 0 0 1 9 0Z" stroke-width="1.7" stroke-linecap="round"/></svg>'
      : '<svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M20.6 15.7A8.5 8.5 0 0 1 8.3 3.4 8.6 8.6 0 1 0 20.6 15.7Z" stroke-width="1.7" stroke-linejoin="round"/></svg>';
  }

  function buildDock() {
    if (document.getElementById('apu-ui-dock-v55')) return;
    const dock = document.createElement('div');
    dock.id = 'apu-ui-dock-v55';
    dock.setAttribute('role', 'group');

    const themeButton = document.createElement('button');
    themeButton.type = 'button';
    themeButton.className = 'apu-ui-button-v55';
    themeButton.dataset.apuAction = 'theme';
    themeButton.addEventListener('click', () => setTheme(root.dataset.apuTheme === 'dark' ? 'light' : 'dark', true));

    const languageWrap = document.createElement('label');
    languageWrap.className = 'apu-ui-language-wrap-v55';
    languageWrap.innerHTML = '<svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><circle cx="12" cy="12" r="9" stroke-width="1.7"/><path d="M3.5 12h17M12 3c2.3 2.5 3.5 5.5 3.5 9S14.3 18.5 12 21c-2.3-2.5-3.5-5.5-3.5-9S9.7 5.5 12 3Z" stroke-width="1.7"/></svg>';
    const select = document.createElement('select');
    select.className = 'apu-ui-language-v55';
    select.dataset.apuAction = 'language';
    for (const [code, info] of Object.entries(LANGUAGES)) {
      const option = document.createElement('option');
      option.value = code;
      option.textContent = info.name;
      select.appendChild(option);
    }
    select.addEventListener('change', event => setLanguage(event.target.value, true));
    languageWrap.appendChild(select);

    dock.append(themeButton, languageWrap);
    document.body.appendChild(dock);

    const toast = document.createElement('div');
    toast.id = 'apu-ui-toast-v55';
    toast.setAttribute('role', 'status');
    toast.setAttribute('aria-live', 'polite');
    document.body.appendChild(toast);
    updateDock();
  }

  function updateDock() {
    const dock = document.getElementById('apu-ui-dock-v55');
    if (!dock) return;
    const themeButton = dock.querySelector('[data-apu-action="theme"]');
    const languageWrap = dock.querySelector('.apu-ui-language-wrap-v55');
    const select = dock.querySelector('[data-apu-action="language"]');
    const ui = UI[currentLanguage] || UI.en;
    const currentTheme = root.dataset.apuTheme || 'light';
    themeButton.innerHTML = iconForTheme(currentTheme);
    themeButton.title = ui.theme;
    themeButton.setAttribute('aria-label', ui.theme);
    themeButton.setAttribute('aria-pressed', String(currentTheme === 'dark'));
    select.value = currentLanguage;
    select.title = ui.language;
    select.setAttribute('aria-label', ui.language);
    languageWrap.dataset.shortLabel = LANGUAGES[currentLanguage].short;
  }

  function showToast(message) {
    const toast = document.getElementById('apu-ui-toast-v55');
    if (!toast) return;
    clearTimeout(toastTimer);
    toast.textContent = message;
    toast.dataset.show = 'true';
    toastTimer = window.setTimeout(() => { toast.dataset.show = 'false'; }, 1800);
  }

  function init() {
    buildDock();
    setTheme(root.dataset.apuTheme || 'light', false);
    setLanguage(root.dataset.apuLanguage || 'en', false);
    observer = new MutationObserver(mutations => {
      for (const mutation of mutations) {
        if (mutation.type === 'childList' && mutation.addedNodes.length) {
          const target = mutation.target.nodeType === 1 ? mutation.target : mutation.target.parentElement;
          if (target && !target.closest?.('#apu-ui-dock-v55, #apu-ui-toast-v55')) queueTranslation(target);
        }
      }
    });
    observer.observe(document.body, { childList: true, subtree: true });
  }

  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init, { once: true });
  else init();
})();
