document.querySelectorAll('[data-ticket-composer]').forEach(form=>{ const canonical=form.querySelector('input[name="files"]'),preview=form.querySelector('[data-file-preview]'); if(!canonical||!preview)return; canonical.classList.add('canonical-file-input'); let files=[]; const status=form.querySelector('[data-compression-status]'); const compress=file=>new Promise(resolve=>{ if(!file.type.startsWith('image/')||file.type==='image/gif'||typeof Compressor==='undefined')return resolve(file); new Compressor(file,{quality:.76,maxWidth:1920,maxHeight:1920,convertSize:1500000,success(blob){const ext=blob.type==='image/jpeg'?'.jpg':file.name.match(/\.[^.]+$/)?.[0]||'.jpg';resolve(new File([blob],file.name.replace(/\.[^.]+$/,ext),{type:blob.type,lastModified:Date.now()}))},error(){resolve(file)}}); }); const sync=()=>{const dt=new DataTransfer();files.forEach(file=>dt.items.add(file));canonical.files=dt.files;preview.replaceChildren();files.forEach((file,index)=>{const item=document.createElement('div');item.className='file-chip';if(file.type.startsWith('image/')){const img=document.createElement('img');const url=URL.createObjectURL(file);img.src=url;img.onload=()=>URL.revokeObjectURL(url);item.appendChild(img)}const name=document.createElement('small');name.textContent=`${file.name} · ${(file.size/1024/1024).toFixed(1)} MB`;item.appendChild(name);const remove=document.createElement('button');remove.type='button';remove.textContent='×';remove.setAttribute('aria-label','حذف فایل');remove.onclick=()=>{files.splice(index,1);sync()};item.appendChild(remove);preview.appendChild(item)})}; const add=async selected=>{if(status)status.textContent='در حال بهینه‌سازی تصاویر…';const prepared=await Promise.all(Array.from(selected).map(compress));files=[...files,...prepared];sync();if(status)status.textContent='تصاویر آماده ارسال هستند؛ نسخه اصلی روی گوشی شما تغییری نکرده است.'}; form.querySelectorAll('[data-gallery-input],[data-document-input]').forEach(input=>input.addEventListener('change',async()=>{await add(input.files);input.value=''})); canonical.addEventListener('change',async()=>{if(canonical.dataset.syncing)return;const selected=Array.from(canonical.files);canonical.value='';await add(selected)}); form.addEventListener('voice-added',event=>{files=[...files,event.detail];sync()}); form.addEventListener('voice-removed',event=>{files=files.filter(file=>file!==event.detail);sync()}); form.addEventListener('submit',()=>form.querySelectorAll('button[type=submit],button:not([type])').forEach(button=>button.disabled=true)); });