import {cropGeometry} from './profile-crop.mjs'; const el=id=>document.getElementById(id),form=el('profile-form'),canvas=el('profile-crop-canvas'),ctx=canvas.getContext('2d'); let savedPhoto=null,draftPhoto=null,bitmap=null,version=0,drag=null; const controls=[el('profile-photo-zoom'),el('profile-photo-x'),el('profile-photo-y')]; function release(){version++;bitmap?.close();bitmap=null;el('profile-crop-editor').hidden=true;el('profile-photo-file').value=''} function photoInto(node,url){node.replaceChildren();if(url){const img=document.createElement('img');img.src=url;img.alt='Foto do perfil';img.dataset.profilePhoto='';node.append(img)}else node.textContent=el('display-name').value.trim().split(/\s+/).slice(0,2).map(n=>n[0]||'').join('').toUpperCase()||'NA'} function preview(){photoInto(el('profile-photo-preview'),draftPhoto);el('profile-photo-remove').hidden=!draftPhoto&&!bitmap} function updateAvatars(){if(!savedPhoto)return;document.querySelectorAll('[data-avatar],#publish-avatar').forEach(node=>{if(node.querySelector('img[data-profile-photo]')?.getAttribute('src')!==savedPhoto)photoInto(node,savedPhoto)})} function geometry(size=320){return cropGeometry(bitmap.width,bitmap.height,Number(controls[0].value),Number(controls[1].value),Number(controls[2].value),size)} function draw(){if(!bitmap)return;const g=geometry();ctx.clearRect(0,0,320,320);ctx.drawImage(bitmap,g.x,g.y,g.width,g.height)} function applyCrop(){if(!bitmap)return;const output=document.createElement('canvas');output.width=output.height=512;const g=geometry(512);output.getContext('2d').drawImage(bitmap,g.x,g.y,g.width,g.height);draftPhoto=output.toDataURL('image/jpeg',0.9);release();preview();el('profile-photo-status').textContent='Recorte pronto. Clique em Salvar na prévia para confirmar a foto.'} const originalOpen=window.openDialog;window.openDialog=function(...args){originalOpen(...args);if(args[2]){release();draftPhoto=savedPhoto;el('profile-photo-status').textContent='';preview()}}; const originalClose=window.closeDialog;window.closeDialog=function(...args){release();draftPhoto=savedPhoto;return originalClose(...args)}; el('profile-photo-file').addEventListener('change',async()=>{const file=el('profile-photo-file').files[0];if(!file)return;release();const token=version;if(!['image/jpeg','image/png','image/webp'].includes(file.type)||file.size>10*1024*1024){el('profile-photo-status').textContent='Escolha JPG, PNG ou WebP de até 10 MB.';return}el('profile-photo-status').textContent='Preparando sua foto…';try{const decoded=await createImageBitmap(file,{imageOrientation:'from-image'});if(token!==version){decoded.close();return}if(decoded.width>8192||decoded.height>8192||decoded.width*decoded.height>40000000){decoded.close();throw new Error('dimensions')}bitmap=decoded;controls[0].value='1';controls[1].value=controls[2].value='0';el('profile-crop-editor').hidden=false;el('profile-photo-status').textContent='Ajuste o enquadramento antes de usar o recorte.';preview();draw();controls[0].focus()}catch{if(token===version)el('profile-photo-status').textContent='Não foi possível abrir esta foto. Tente outra imagem de até 8192 pixels por lado.'}}); controls.forEach(input=>input.addEventListener('input',draw)); canvas.addEventListener('pointerdown',event=>{if(!bitmap)return;drag={x:event.clientX,y:event.clientY,panX:Number(controls[1].value),panY:Number(controls[2].value)};canvas.setPointerCapture(event.pointerId)}); canvas.addEventListener('pointermove',event=>{if(!drag||!bitmap)return;const g=geometry(),ratio=320/canvas.getBoundingClientRect().width;controls[1].value=String(g.width>320?Math.max(-1,Math.min(1,drag.panX+(event.clientX-drag.x)*ratio/((g.width-320)/2))):0);controls[2].value=String(g.height>320?Math.max(-1,Math.min(1,drag.panY+(event.clientY-drag.y)*ratio/((g.height-320)/2))):0);draw()}); ['pointerup','pointercancel','lostpointercapture'].forEach(name=>canvas.addEventListener(name,()=>drag=null)); el('profile-photo-apply').addEventListener('click',applyCrop); el('profile-photo-remove').addEventListener('click',()=>{release();draftPhoto=null;preview();el('profile-photo-status').textContent='Foto removida da edição. Salve o perfil para confirmar.'}); form.addEventListener('submit',()=>{if(!form.checkValidity()||!el('display-name').value.trim())return;applyCrop();savedPhoto=draftPhoto;queueMicrotask(()=>{if(savedPhoto)updateAvatars();else document.querySelectorAll('[data-avatar],#publish-avatar').forEach(node=>photoInto(node,null))})},true); // Existing renderers may restore initials; repaint only this member's marked avatars. new MutationObserver(updateAvatars).observe(el('app'),{childList:true,subtree:true}); el('logout').addEventListener('click',()=>{savedPhoto=draftPhoto=null;release();document.querySelectorAll('[data-avatar],#publish-avatar').forEach(node=>photoInto(node,null))}); window.addEventListener('beforeunload',release); ['cancel-profile','close-dialog'].forEach(id=>el(id).addEventListener('click',()=>{release();draftPhoto=savedPhoto}));