function applyTheme(){
  const saved=localStorage.getItem('qr-theme')||'auto';
  document.documentElement.dataset.theme=saved;
  document.querySelectorAll('[data-theme-toggle]').forEach(b=>b.textContent=saved==='dark'?'Light Mode':'Dark Mode');
}
function loadImage(src){return new Promise((resolve,reject)=>{if(!src) return resolve(null); const img=new Image(); img.onload=()=>resolve(img); img.onerror=reject; img.src=src;});}
function drawLogo(canvas,img){
  if(!img) return;
  const ctx=canvas.getContext('2d');
  const size=canvas.width;
  const box=Math.round(size*0.22);
  const pad=Math.round(size*0.025);
  const x=Math.round((size-box)/2), y=x;
  ctx.fillStyle='#ffffff';
  ctx.beginPath(); ctx.roundRect(x-pad,y-pad,box+pad*2,box+pad*2,Math.round(size*0.035)); ctx.fill();
  const scale=Math.min(box/img.width,box/img.height);
  const w=Math.round(img.width*scale), h=Math.round(img.height*scale);
  ctx.drawImage(img,Math.round((size-w)/2),Math.round((size-h)/2),w,h);
}
async function renderQr(el){
  if(typeof QRCode==='undefined'){
    const msg=document.createElement('p'); msg.className='notice'; msg.textContent='QR-Bibliothek konnte nicht geladen werden. Bitte Internetverbindung/CDN-Zugriff pruefen oder die Bibliothek lokal einbinden.'; el.replaceWith(msg); return;
  }
  const text=el.dataset.text; const fg=el.dataset.fg||'#000000'; const bg=el.dataset.transparent==='1'?'#00000000':(el.dataset.bg||'#ffffff'); const size=parseInt(el.getAttribute('width')||el.clientWidth||256,10);
  QRCode.toCanvas(el, text, {width:size,margin:2,color:{dark:fg,light:bg},errorCorrectionLevel:el.dataset.logo?'H':'M'}, async err=>{
    if(err){const msg=document.createElement('p'); msg.className='notice'; msg.textContent='QR-Code konnte nicht erzeugt werden: '+err.message; el.replaceWith(msg); return;}
    try{drawLogo(el, await loadImage(el.dataset.logo));}catch(e){console.warn('Logo konnte nicht geladen werden',e);}
  });
}
async function canvasSvgWithLogo(canvas, baseSvg){
  if(!canvas.dataset.logo) return baseSvg;
  const dataUrl = await imageToDataUrl(canvas.dataset.logo);
  const size=parseInt(canvas.getAttribute('width')||256,10);
  const box=Math.round(size*0.22); const pad=Math.round(size*0.025); const x=Math.round((size-box)/2); const y=x;
  const insert=`<rect x="${x-pad}" y="${y-pad}" width="${box+pad*2}" height="${box+pad*2}" rx="${Math.round(size*0.035)}" fill="#ffffff"/><image href="${dataUrl}" x="${x}" y="${y}" width="${box}" height="${box}" preserveAspectRatio="xMidYMid meet"/>`;
  return baseSvg.replace('</svg>',insert+'</svg>');
}
function imageToDataUrl(src){return new Promise((resolve,reject)=>{const img=new Image(); img.onload=()=>{const c=document.createElement('canvas'); c.width=img.width; c.height=img.height; c.getContext('2d').drawImage(img,0,0); resolve(c.toDataURL('image/png'));}; img.onerror=reject; img.src=src;});}
async function makeDownload(canvas, type, name){
  if(!canvas || canvas.tagName.toLowerCase()!=='canvas') return alert('QR-Code ist noch nicht bereit.');
  if(typeof QRCode==='undefined') return alert('QR-Bibliothek konnte nicht geladen werden.');
  if(type==='svg'){
    QRCode.toString(canvas.dataset.text,{type:'svg',margin:2,color:{dark:canvas.dataset.fg||'#000',light:canvas.dataset.transparent==='1'?'#00000000':(canvas.dataset.bg||'#fff')},errorCorrectionLevel:canvas.dataset.logo?'H':'M'},async (err,svg)=>{
      if(err) return alert(err.message||err); try{svg=await canvasSvgWithLogo(canvas,svg);}catch(e){} const blob=new Blob([svg],{type:'image/svg+xml'}); saveBlob(blob,name+'.svg');
    }); return;
  }
  const mime=type==='jpg'?'image/jpeg':'image/png'; canvas.toBlob(blob=>saveBlob(blob,name+'.'+(type==='jpg'?'jpg':'png')),mime,0.95);
}
function saveBlob(blob, filename){const a=document.createElement('a');a.href=URL.createObjectURL(blob);a.download=filename;document.body.appendChild(a);a.click();a.remove();setTimeout(()=>URL.revokeObjectURL(a.href),1000)}
document.addEventListener('DOMContentLoaded',()=>{
  applyTheme();
  document.querySelectorAll('[data-theme-toggle]').forEach(btn=>btn.addEventListener('click',()=>{const cur=localStorage.getItem('qr-theme')||'auto';localStorage.setItem('qr-theme',cur==='dark'?'light':'dark');applyTheme();}));
  document.querySelectorAll('canvas.qr').forEach(renderQr);
  document.querySelectorAll('[data-download]').forEach(btn=>btn.addEventListener('click',()=>{const c=document.querySelector(btn.dataset.target);makeDownload(c,btn.dataset.download,btn.dataset.name||'qr-code')}));
});

// v8.5: mobile sidebar, live QR preview and nicer colour controls
function debounce(fn, wait){let t; return (...args)=>{clearTimeout(t); t=setTimeout(()=>fn(...args),wait);};}
function normaliseHex(v){v=(v||'').trim(); if(!v.startsWith('#')) v='#'+v; return /^#[0-9a-fA-F]{6}$/.test(v)?v.toUpperCase():null;}
async function renderLivePreview(form){
  const canvas=document.getElementById('qr-live'); if(!canvas || typeof QRCode==='undefined') return;
  const base=form.dataset.baseUrl||'';
  const slug=(form.querySelector('[name="custom_slug"]')?.value||'').trim() || form.dataset.currentCode || 'vorschau';
  const fg=form.querySelector('[name="foreground_color"]')?.value || '#000000';
  const bg=form.querySelector('[name="background_color"]')?.value || '#FFFFFF';
  const transparent=form.querySelector('[name="transparent_background"]')?.checked;
  const removeLogo=form.querySelector('[name="remove_logo"]')?.checked;
  const file=form.querySelector('[name="logo"]')?.files?.[0];
  const text=base+slug;
  canvas.dataset.text=text; canvas.dataset.fg=fg; canvas.dataset.bg=bg; canvas.dataset.transparent=transparent?'1':'0';
  let logoSrc='';
  if(file){logoSrc=URL.createObjectURL(file);} else if(!removeLogo && form.dataset.logoCurrent){logoSrc=form.dataset.logoCurrent;}
  canvas.dataset.logo=logoSrc;
  const out=document.querySelector('[data-live-url]'); if(out) out.textContent=text;
  await new Promise(resolve=>QRCode.toCanvas(canvas,text,{width:320,margin:2,color:{dark:fg,light:transparent?'#00000000':bg},errorCorrectionLevel:logoSrc?'H':'M'},()=>resolve()));
  try{drawLogo(canvas, await loadImage(logoSrc));}catch(e){}
  if(file && logoSrc) setTimeout(()=>URL.revokeObjectURL(logoSrc),2000);
}
document.addEventListener('DOMContentLoaded',()=>{
  const toggle=document.querySelector('[data-menu-toggle]');
  const overlay=document.querySelector('[data-menu-overlay]');
  const closeMenu=()=>{document.body.classList.remove('menu-open'); if(toggle) toggle.setAttribute('aria-expanded','false');};
  if(toggle){toggle.addEventListener('click',()=>{const open=!document.body.classList.contains('menu-open');document.body.classList.toggle('menu-open',open);toggle.setAttribute('aria-expanded',open?'true':'false');});}
  if(overlay) overlay.addEventListener('click',closeMenu);
  document.querySelectorAll('.side-nav a,.logout-link').forEach(a=>a.addEventListener('click',closeMenu));

  document.querySelectorAll('[data-color-hex]').forEach(hex=>{
    const color=document.querySelector('[name="'+hex.dataset.colorHex+'"]');
    if(!color) return;
    color.addEventListener('input',()=>{hex.value=color.value.toUpperCase();});
    hex.addEventListener('change',()=>{const v=normaliseHex(hex.value); if(v){color.value=v; hex.value=v; color.dispatchEvent(new Event('input',{bubbles:true}));} else {hex.value=color.value.toUpperCase();}});
  });
  document.querySelectorAll('[data-qr-editor]').forEach(form=>{
    const update=debounce(()=>renderLivePreview(form),120);
    form.querySelectorAll('input,select').forEach(el=>el.addEventListener('input',update));
    form.querySelectorAll('input,select').forEach(el=>el.addEventListener('change',update));
    renderLivePreview(form);
  });
});

// v11: statistics selection helpers
// Keeps the statistics screen usable without losing form state.
document.addEventListener('DOMContentLoaded',()=>{
  document.querySelectorAll('[data-check-all]').forEach(master=>{
    const selector=master.dataset.checkAll;
    const items=()=>Array.from(document.querySelectorAll(selector));
    master.addEventListener('change',()=>items().forEach(cb=>{cb.checked=master.checked;}));
    items().forEach(cb=>cb.addEventListener('change',()=>{
      const all=items();
      master.checked=all.length>0 && all.every(x=>x.checked);
      master.indeterminate=all.some(x=>x.checked) && !master.checked;
    }));
  });
  document.querySelectorAll('[data-uncheck-all]').forEach(btn=>{
    btn.addEventListener('click',()=>{
      document.querySelectorAll(btn.dataset.uncheckAll).forEach(cb=>{cb.checked=false;});
      document.querySelectorAll('[data-check-all]').forEach(cb=>{cb.checked=false;cb.indeterminate=false;});
    });
  });
});

// v14: password visibility toggle
// Handles multiple password fields on one form.
document.addEventListener('DOMContentLoaded',()=>{
  document.querySelectorAll('[data-password-toggle-button]').forEach(btn=>{
    const wrap=btn.closest('.password-field');
    const input=wrap ? wrap.querySelector('[data-password-toggle]') : null;
    if(!input) return;
    btn.addEventListener('click',()=>{
      const show=input.type==='password';
      input.type=show?'text':'password';
      btn.classList.toggle("is-visible", show);
      btn.setAttribute("aria-pressed",show?"true":"false");
      btn.setAttribute("aria-label",show?"Passwort verbergen":"Passwort anzeigen");
      input.focus();
    });
  });
});

// v18: show logo preloader while forms and normal navigation process
(function(){
  const showLoader=()=>{const p=document.querySelector('[data-preloader]'); if(p){p.classList.add('is-active'); p.setAttribute('aria-hidden','false');}};
  const hideLoader=()=>{const p=document.querySelector('[data-preloader]'); if(p){p.classList.remove('is-active'); p.setAttribute('aria-hidden','true');}};
  window.addEventListener('pageshow',hideLoader);
  document.addEventListener('DOMContentLoaded',()=>{
    document.querySelectorAll('form').forEach(form=>form.addEventListener('submit',()=>showLoader()));
    document.addEventListener('click',(event)=>{
      const link=event.target.closest('a');
      if(!link) return;
      const href=link.getAttribute('href')||'';
      if(!href || href.startsWith('#') || href.startsWith('mailto:') || href.startsWith('tel:') || link.target==='_blank' || link.hasAttribute('download')) return;
      showLoader();
    });
  });
})();
