(function(){
  const root=document.querySelector('[data-pos-app]');
  const base=(window.PH_BASE||'/').replace(/\/$/,'')+'/';
  const pos=window.PH_POS||{};
  const money=n=>'৳ '+(Number(n||0)).toLocaleString(undefined,{minimumFractionDigits:2,maximumFractionDigits:2});
  let deferredInstall=null;
  let cart=Array.isArray(window.PH_HELD_CART)?window.PH_HELD_CART:JSON.parse(localStorage.getItem('ph_pos_cart')||'[]');
  function api(path){return base+path.replace(/^\//,'');}
  function save(){localStorage.setItem('ph_pos_cart',JSON.stringify(cart));}
  function totals(){let sub=cart.reduce((s,i)=>s+(Number(i.price)||0)*(Number(i.qty)||1),0);let disc=Math.min(sub,Math.max(0,Number(document.getElementById('posDiscount')?.value||0)));let taxPercent=Math.max(0,Number(document.getElementById('posTaxPercent')?.value||0));let tax=(sub-disc)*taxPercent/100;let total=sub-disc+tax;return {subtotal:sub,discount:disc,tax:tax,total:total};}
  function renderCart(){const body=document.getElementById('posCartBody');if(!body)return;if(!cart.length){body.innerHTML='<tr><td colspan="5" class="text-center text-muted py-4">Scan or tap a product.</td></tr>';}else{body.innerHTML=cart.map((i,idx)=>`<tr><td><strong>${escapeHtml(i.name)}</strong><br><small class="text-muted">${escapeHtml(i.sku||'')} ${escapeHtml(i.barcode||'')}</small></td><td><input class="form-control form-control-sm" type="number" min="1" value="${i.qty}" data-cart-qty="${idx}"></td><td><input class="form-control form-control-sm" type="number" step="0.01" value="${i.price}" data-cart-price="${idx}"></td><td>${money((Number(i.price)||0)*(Number(i.qty)||1))}</td><td><button class="remove" type="button" data-cart-remove="${idx}">x</button></td></tr>`).join('');}
    const t=totals();setText('posSubtotal',money(t.subtotal));setText('posDiscountView',money(t.discount));setText('posTaxView',money(t.tax));setText('posGrandTotal',money(t.total));const paid=document.getElementById('posPaidAmount');if(paid&&!paid.value)paid.value=t.total.toFixed(2);save();}
  function setText(id,text){let el=document.getElementById(id);if(el)el.textContent=text;}
  function escapeHtml(s){return String(s||'').replace(/[&<>"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[c]));}
  function addProduct(p){let id=Number(p.id||p.product_id);let found=cart.find(i=>Number(i.product_id)===id);if(found){found.qty=Number(found.qty||1)+1;}else{cart.push({product_id:id,name:p.name||'',sku:p.sku||'',barcode:p.barcode||'',price:Number(p.sale_price||p.regular_price||0),qty:1,stock:Number(p.stock||0)});}renderCart();beep();}
  function beep(){try{let ctx=new (window.AudioContext||window.webkitAudioContext)();let o=ctx.createOscillator();let g=ctx.createGain();o.connect(g);g.connect(ctx.destination);o.frequency.value=880;g.gain.value=.04;o.start();setTimeout(()=>{o.stop();ctx.close();},85);}catch(e){}}
  async function search(q){const grid=document.getElementById('posProductGrid');if(!grid)return;grid.innerHTML='<div class="text-muted">Searching...</div>';try{let res=await fetch(api('api/pos-product-search.php?q='+encodeURIComponent(q||'')+'&vendor_id='+(pos.vendor_id||'')),{headers:{'X-CSRF-Token':window.PH_CSRF||''}});let json=await res.json();if(!json.ok)throw new Error(json.message||'Search failed');grid.innerHTML=json.products.map(p=>`<button class="pos-product-tile" type="button" data-product='${JSON.stringify(p).replace(/'/g,'&#39;')}'><span class="pos-product-name">${escapeHtml(p.name)}</span><span class="pos-product-sku">${escapeHtml((p.sku||'')+' / '+(p.barcode||''))}</span><span class="pos-product-price">${money(p.sale_price||p.regular_price||0)}</span><span class="pos-stock">Stock: ${escapeHtml(p.stock||0)}</span></button>`).join('')||'<div class="text-muted">No products found.</div>';}catch(e){grid.innerHTML='<div class="text-danger">Could not search products.</div>';}}
  async function addByCode(code){code=String(code||'').trim();if(!code)return;try{let res=await fetch(api('api/pos-product-search.php?code='+encodeURIComponent(code)+'&vendor_id='+(pos.vendor_id||'')),{headers:{'X-CSRF-Token':window.PH_CSRF||''}});let json=await res.json();if(json.ok&&json.product){addProduct(json.product);message('Added '+json.product.name,'success');}else{message(json.message||'Product not found','danger');}}catch(e){message('Lookup failed. Use manual search or check connection.','danger');}}
  async function completeSale(){if(!cart.length)return message('Cart is empty.','danger');let t=totals();let paid=Number(document.getElementById('posPaidAmount')?.value||0);if(paid<t.total)return message('Paid amount is lower than total.','danger');let payload={vendor_id:pos.vendor_id,register_id:pos.register_id,shift_id:pos.shift_id,items:cart,discount_amount:t.discount,tax_percent:Number(document.getElementById('posTaxPercent')?.value||0),customer_text:document.getElementById('posCustomer')?.value||'',payments:[{method:document.getElementById('posPaymentMethod')?.value||'cash',amount:paid,reference_no:document.getElementById('posPaymentRef')?.value||''}]};if(!navigator.onLine){queueOfflineSale(payload);cart=[];renderCart();return message('Offline: sale stored in local queue. Sync when internet returns.','warning');}
    try{let res=await fetch(api('api/pos-checkout.php'),{method:'POST',headers:{'Content-Type':'application/json','X-CSRF-Token':window.PH_CSRF||''},body:JSON.stringify(payload)});let json=await res.json();if(!json.ok)throw new Error(json.message||'Checkout failed');cart=[];localStorage.removeItem('ph_pos_cart');renderCart();message('Sale '+json.sale_no+' completed. Change: '+money(json.change),'success');if(window.phPrintReceipt)window.phPrintReceipt(json.sale_id,true);}catch(e){message(e.message||'Could not complete sale.','danger');}}
  function queueOfflineSale(payload){let q=JSON.parse(localStorage.getItem('ph_pos_offline_queue')||'[]');q.push({uuid:'offline-'+Date.now()+'-'+Math.random().toString(16).slice(2),payload:payload,created_at:new Date().toISOString()});localStorage.setItem('ph_pos_offline_queue',JSON.stringify(q));}
  async function syncQueue(){let q=JSON.parse(localStorage.getItem('ph_pos_offline_queue')||'[]');if(!q.length||!navigator.onLine)return;let remaining=[];for(const item of q){try{let res=await fetch(api('api/pos-sync.php'),{method:'POST',headers:{'Content-Type':'application/json','X-CSRF-Token':window.PH_CSRF||''},body:JSON.stringify(item)});let json=await res.json();if(!json.ok)remaining.push(item);}catch(e){remaining.push(item);}}localStorage.setItem('ph_pos_offline_queue',JSON.stringify(remaining));if(q.length!==remaining.length)message('Offline sales synced: '+(q.length-remaining.length),'success');}
  async function holdSale(){if(!cart.length)return message('Cart is empty.','danger');let t=totals();try{let res=await fetch(api('api/pos-held-sales.php'),{method:'POST',headers:{'Content-Type':'application/json','X-CSRF-Token':window.PH_CSRF||''},body:JSON.stringify({action:'hold',vendor_id:pos.vendor_id,register_id:pos.register_id,shift_id:pos.shift_id,customer_name:document.getElementById('posCustomer')?.value||'',items:cart,total_amount:t.total})});let json=await res.json();if(!json.ok)throw new Error(json.message||'Hold failed');cart=[];renderCart();message('Sale held: '+json.hold_no,'success');}catch(e){message(e.message||'Could not hold sale.','danger');}}
  function message(text,type){let el=document.getElementById('posMessage')||document.getElementById('scannerStatus');if(el){el.className='small mt-2 text-'+(type||'muted');el.textContent=text;}else alert(text);}
  window.phPosAddProduct=addProduct;window.phPosAddByCode=addByCode;window.phPosSyncQueue=syncQueue;
  window.addEventListener('beforeinstallprompt',e=>{e.preventDefault();deferredInstall=e;});window.addEventListener('online',syncQueue);
  document.addEventListener('DOMContentLoaded',()=>{renderCart();syncQueue();document.querySelectorAll('[data-product]').forEach(btn=>btn.addEventListener('click',()=>{try{addProduct(JSON.parse(btn.dataset.product));}catch(e){}}));document.body.addEventListener('click',e=>{let t=e.target;if(t.matches('[data-pos-search]'))search(document.getElementById('posSearch')?.value||'');if(t.matches('[data-refresh-products]'))search('');if(t.matches('[data-clear-cart]')){cart=[];renderCart();}if(t.matches('[data-hold-sale]'))holdSale();if(t.matches('[data-complete-sale]'))completeSale();if(t.matches('[data-pay-method]')){let m=t.getAttribute('data-pay-method');let sel=document.getElementById('posPaymentMethod');if(sel)sel.value=m;let paid=document.getElementById('posPaidAmount');if(paid)paid.value=totals().total.toFixed(2);}if(t.matches('[data-cart-remove]')){cart.splice(Number(t.dataset.cartRemove),1);renderCart();}if(t.matches('[data-pos-install]')&&deferredInstall){deferredInstall.prompt();deferredInstall=null;}if(t.matches('[data-load-held]'))location.href=api('pos/register.php?held_id='+encodeURIComponent(t.dataset.loadHeld));if(t.matches('[data-delete-held]'))deleteHeld(t.dataset.deleteHeld);});document.body.addEventListener('change',e=>{let t=e.target;if(t.matches('[data-cart-qty]')){cart[Number(t.dataset.cartQty)].qty=Math.max(1,Number(t.value||1));renderCart();}if(t.matches('[data-cart-price]')){cart[Number(t.dataset.cartPrice)].price=Math.max(0,Number(t.value||0));renderCart();}if(t.id==='posDiscount'||t.id==='posTaxPercent')renderCart();});let barcode=document.getElementById('barcodeInput');if(barcode){barcode.addEventListener('keydown',e=>{if(e.key==='Enter'){e.preventDefault();addByCode(barcode.value);barcode.value='';}});}let refund=document.getElementById('posRefundForm');if(refund){refund.addEventListener('submit',async e=>{e.preventDefault();let fd=new FormData(refund);try{let res=await fetch(api('api/pos-refund.php'),{method:'POST',headers:{'X-CSRF-Token':window.PH_CSRF||''},body:fd});let json=await res.json();document.getElementById('refundMessage').textContent=json.message||'';if(json.ok)setTimeout(()=>location.reload(),800);}catch(err){document.getElementById('refundMessage').textContent='Refund failed.';}});}});
  async function deleteHeld(id){if(!confirm('Delete held sale?'))return;let res=await fetch(api('api/pos-held-sales.php'),{method:'POST',headers:{'Content-Type':'application/json','X-CSRF-Token':window.PH_CSRF||''},body:JSON.stringify({action:'delete',id:id})});let json=await res.json();if(json.ok)location.reload();else alert(json.message||'Delete failed');}
})();
