import {brand} from './brand.js';
export const LANGUAGES = Object.freeze({fr:'Français',nl:'Nederlands',en:'English',de:'Deutsch',es:'Español',it:'Italiano',pt:'Português',pl:'Polski',ar:'العربية',zh:'简体中文'});
const key='transferwing-language';
let saved;try{saved=localStorage.getItem(key);}catch{}
const system=(navigator.language||'fr').split('-')[0];
let language=Object.hasOwn(LANGUAGES,saved)?saved:Object.hasOwn(LANGUAGES,system)?system:'fr';
let native={},source={},translated={},lookup=new Map(),patterns=[],revision=0;
const texts=new WeakMap(),attributes=new WeakMap(),cache=new Map();
const originalTitle=document.title;
const excluded='script,style,noscript,textarea,[translate="no"],.selected-file,.share-card h3,.share-summary,.receive-file-info,#account-email,#admin-accounts td,.session-identity strong,.event-detail,#transfer-branding,#branding-preview-name,#branding-preview-message';
const normalize=s=>s.replace(/\s+/g,' ').trim();
const baseBrand=['Transfer','Wing'].join('');
const canonical=s=>brand.name==='Relyo'?s.replaceAll('Relyo',baseBrand):s;
const branded=s=>brand.name==='Relyo'?s.replaceAll(baseBrand,'Relyo'):s;
async function load(lang){if(!cache.has(lang))cache.set(lang,fetch(`/locales/${lang}.json`).then(r=>{if(!r.ok)throw Error('Translation unavailable');return r.json()}));return cache.get(lang);}
function prepare(){lookup=new Map(Object.entries(source).map(([id,text])=>[normalize(text),id]));patterns=[];for(const [id,text] of Object.entries(source)){if(!/\{\w+\}/.test(text))continue;const names=[];let escaped=text.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');escaped=escaped.replace(/\\\{(\w+)\\\}/g,(_,name)=>{names.push(name);return '(.+?)'});patterns.push({id,names,re:new RegExp(branded('^'+escaped+'$'))});}}
export function translateText(value){if(typeof value!=='string'||!Object.keys(source).length)return value;const text=canonical(normalize(value));const unit=text.match(/^([\d\s.,]+) (Go|Mo|Ko|To|Gio|Mio|Kio|Tio|octets?)$/);if(unit){const unitId=lookup.get(unit[2]);if(unitId)return unit[1]+' '+(translated[unitId]||source[unitId]);}
const id=lookup.get(text);if(id)return branded(translated[id]||source[id]);for(const pattern of patterns){const match=pattern.re.exec(normalize(value));if(!match)continue;let result=branded(translated[pattern.id]||source[pattern.id]);pattern.names.forEach((name,i)=>{result=result.replaceAll('{'+name+'}',match[i+1]);});return result;}return value;}
export function nativeText(id,values={}){let result=native[id]||id;for(const [key,value] of Object.entries(values))result=result.replaceAll('{'+key+'}',value);return result;}
export function currentLanguage(){return language;}
let observer,scheduled=false;
function apply(){observer?.disconnect();
 const walker=document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT);let n;
 while((n=walker.nextNode())){if(!n.parentElement||n.parentElement.closest(excluded)||!n.textContent.trim())continue;let record=texts.get(n);if(!record||record.last!==n.textContent)record={original:n.textContent};const original=record.original;const result=translateText(original);const output=result===original?original:(original.match(/^\s*/)[0]+result+original.match(/\s*$/)[0]);if(n.textContent!==output)n.textContent=output;record.last=output;texts.set(n,record);}
 for(const el of document.querySelectorAll('[placeholder],[aria-label],[title]')){if(el.closest('[translate="no"]'))continue;let map=attributes.get(el)||{};for(const name of ['placeholder','aria-label','title']){if(!el.hasAttribute(name))continue;const value=el.getAttribute(name);if(!map[name]||map[name].last!==value)map[name]={original:value};const output=translateText(map[name].original);if(output!==value)el.setAttribute(name,output);map[name].last=output;}attributes.set(el,map);}
 document.title=translateText(originalTitle);
 document.documentElement.lang=language;document.documentElement.dir=language==='ar'?'rtl':'ltr';
 document.querySelectorAll('[data-language-selector]').forEach(select=>{select.value=language;select.setAttribute('aria-label',translateText('Langue'));});
 observer?.observe(document.body,{childList:true,subtree:true,characterData:true});
}
export async function setLanguage(lang){if(!Object.hasOwn(LANGUAGES,lang))return;const sequence=++revision;try{const [fr,local,dialogs]=await Promise.all([load('fr'),load(lang),load('native-'+lang).catch(()=>load('native-fr'))]);if(sequence!==revision)return;source=fr;translated=local;native=dialogs;language=lang;window.desktop?.setLanguage?.(lang)?.catch(()=>{});prepare();try{localStorage.setItem(key,lang)}catch{}apply();document.dispatchEvent(new CustomEvent('languagechange',{detail:{language:lang}}));}catch{if(!Object.keys(source).length){source=await load('fr').catch(()=>({}));translated=source;language='fr';prepare();apply();}}}
export function languageSelector(){return `<label class="language-picker" translate="no"><span aria-hidden="true">◎</span><select data-language-selector aria-label="Langue">${Object.entries(LANGUAGES).map(([code,name])=>`<option value="${code}"${code===language?' selected':''}>${name}</option>`).join('')}</select></label>`;}
async function start(){if(window.desktop?.getLanguage){try{const saved=await window.desktop.getLanguage();if(Object.hasOwn(LANGUAGES,saved))language=saved;}catch{}}document.addEventListener('change',e=>{if(e.target.matches('[data-language-selector]'))void setLanguage(e.target.value);});observer=new MutationObserver(()=>{if(scheduled)return;scheduled=true;requestAnimationFrame(()=>{scheduled=false;apply();});});observer.observe(document.body,{childList:true,subtree:true,characterData:true});void setLanguage(language);}
if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',start,{once:true});else start();
