/**
 * cPanel path: /home/jewellersbd/public_html/erp.jewellersbd.com/ui/js/new_stock.js
 * নতুন স্টক মডিউল — list/add/edit/delete/transfer-to-barcode
 * Safe API compatible
 * Barcode modal: item category dropdown + karat dropdown
 */
(function(){
  'use strict';

  var BHARI = 11.664, ANA = BHARI / 16, ROTI = BHARI / 96, POINT = BHARI / 960;
  var KARAT_RATIO = {'24K':100,'22K':91.667,'21K':87.5,'18K':75,'other':91.667};
  var KARAT_CLASS = {'24K':'k-24','22K':'k-22','21K':'k-21','18K':'k-18','other':'k-other'};

  var ITEM_CATEGORIES = [
    'চেইন',
    'আংটি',
    'বালা',
    'চুড়ি',
    'কানের দুল',
    'নাকফুল',
    'লকেট',
    'হার',
    'নেকলেস',
    'ব্রেসলেট',
    'পায়েল',
    'টিকলি',
    'অন্যান্য'
  ];

  var API_BASE = '../api/new_stock/';
  var PARTIES_API = '../api/parties/get_parties.php?limit=500';
  var ADD_PARTY_API = '../api/parties/add_party.php';
  var CASH_API = '../api/cash/get_accounts.php';

  var partiesList = [];
  var accountsList = [];
  var stockList = [];
  var activePartyContext = 'm';
  var activeBarcodeStock = null;
  var bcItems = [];

  function G(id){ return document.getElementById(id); }

  function tk(n){
    return '৳' + Number(parseFloat(n || 0).toFixed(0)).toLocaleString('en-IN');
  }

  function bn(n){
    var d = '০১২৩৪৫৬৭৮৯';
    return String(n).replace(/\d/g, function(x){ return d[x]; });
  }

  function esc(s){
    return String(s || '').replace(/[&<>"']/g, function(c){
      return {'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c];
    });
  }

  function todayStr(){
    return new Date().toISOString().split('T')[0];
  }

  function bnDate(d){
    if(!d) return '';
    var p = String(d).split(' ')[0].split('-');
    if(p.length !== 3) return bn(d);
    return bn(p[2] + '/' + p[1] + '/' + p[0]);
  }

  function num(v){
    var x = parseFloat(v);
    return isNaN(x) ? 0 : x;
  }

  function intNum(v){
    var x = parseInt(v, 10);
    return isNaN(x) ? 0 : x;
  }

  function karatRatio(k){
    return KARAT_RATIO[k] || 91.667;
  }

  function pureFromGross(gross, karat){
    return num(gross) * (karatRatio(karat) / 100);
  }

  function gramToWeight(gram){
    gram = num(gram);
    if(gram <= 0) return {vori:0, ana:0, roti:0, point:0};

    var pts = Math.round(gram / POINT);
    var v = Math.floor(pts / 960); pts -= v * 960;
    var a = Math.floor(pts / 60);  pts -= a * 60;
    var r = Math.floor(pts / 10);  pts -= r * 10;

    return {vori:v, ana:a, roti:r, point:pts};
  }

  function weightToGram(v, a, r, p){
    return num(v) * BHARI + num(a) * ANA + num(r) * ROTI + num(p) * POINT;
  }

  function itemCategoryValue(name){
    name = String(name || '').trim();
    if(!name) return 'চেইন';
    return ITEM_CATEGORIES.indexOf(name) >= 0 ? name : 'অন্যান্য';
  }

  function itemCategoryOptions(selected){
    selected = itemCategoryValue(selected);
    var html = '';

    ITEM_CATEGORIES.forEach(function(c){
      html += '<option value="' + esc(c) + '"' + (selected === c ? ' selected' : '') + '>' + esc(c) + '</option>';
    });

    return html;
  }

  function getBarcodeItemName(item, fallback){
    var category = String(item.category || item.name || '').trim();

    if(category && category !== 'অন্যান্য'){
      return category;
    }

    var custom = String(item.name || '').trim();
    return custom || fallback || 'আইটেম';
  }

  function getBarcodeCategory(item, fallback){
    var name = getBarcodeItemName(item, fallback);
    var cat = String(item.category || '').trim();

    if(cat && cat !== 'অন্যান্য'){
      return cat;
    }

    return name;
  }

  function accountName(a){
    return a.account_name_bn || a.account_name || a.name || ('Account #' + a.id);
  }

  function accountBalance(a){
    return a.current_balance !== undefined ? a.current_balance : (a.balance || 0);
  }

  function apiMessage(res, fallback){
    return res && res.message ? res.message : fallback;
  }

  function showBox(el, msg){
    if(!el) return;
    el.style.display = 'block';
    el.textContent = msg;
  }

  function hideBox(el){
    if(!el) return;
    el.style.display = 'none';
    el.textContent = '';
  }

  function getStockId(r){
    return r.id || r.stock_id || r.new_stock_id || 0;
  }

  function getItemName(r){
    return r.product_name || r.item_name || r.name || r.category || '—';
  }

  function getPureWeight(r){
    var p = num(r.pure_weight_gram || r.pure_weight || r.pure_gold_gram);
    if(p > 0) return p;
    return pureFromGross(num(r.total_weight_gram || r.gross_weight_gram || r.weight_gram || r.weight), r.karat || r.purity || '22K');
  }

  function getAvailablePcs(r){
    if(r.available_pcs !== undefined && r.available_pcs !== null) return intNum(r.available_pcs);
    if(r.balance_pcs !== undefined && r.balance_pcs !== null) return intNum(r.balance_pcs);
    return intNum(r.total_pcs || r.pcs || r.quantity || r.qty);
  }

  function getTotalPcs(r){
    return intNum(r.total_pcs || r.pcs || r.quantity || r.qty);
  }

  function getTotalWeight(r){
    return num(r.total_weight_gram || r.gross_weight_gram || r.weight_gram || r.weight);
  }

  function getAvailableWeight(r){
    if(r.available_weight_gram !== undefined && r.available_weight_gram !== null) return num(r.available_weight_gram);
    if(r.balance_weight_gram !== undefined && r.balance_weight_gram !== null) return num(r.balance_weight_gram);
    return getTotalWeight(r);
  }

  function isUsedStock(r){
    var totalPcs = getTotalPcs(r);
    var availPcs = getAvailablePcs(r);
    var totalW = getTotalWeight(r);
    var availW = getAvailableWeight(r);

    return (totalPcs > availPcs) || ((totalW - availW) > 0.001);
  }

  function loadParties(cb){
    fetch(PARTIES_API, {credentials:'same-origin'})
      .then(function(r){ return r.json(); })
      .then(function(res){
        partiesList = (res && res.data && res.data.parties) ? res.data.parties :
                      (res && res.parties) ? res.parties : [];
        if(typeof cb === 'function') cb();
      })
      .catch(function(){
        partiesList = [];
        if(typeof cb === 'function') cb();
      });
  }

  function loadAccounts(){
    fetch(CASH_API, {credentials:'same-origin'})
      .then(function(r){ return r.json(); })
      .then(function(res){
        accountsList = (res && res.data && res.data.accounts) ? res.data.accounts :
                       (res && res.accounts) ? res.accounts : [];

        ['mCashAcc','mCashAcc2','eCashAcc'].forEach(function(id){
          var sel = G(id);
          if(!sel) return;

          var cur = sel.value;
          sel.innerHTML = '';

          accountsList.forEach(function(a){
            var o = document.createElement('option');
            o.value = a.id;
            o.textContent = accountName(a) + ' (' + tk(accountBalance(a)) + ')';
            sel.appendChild(o);
          });

          if(cur) sel.value = cur;
        });
      })
      .catch(function(){});
  }

  function searchParties(query){
    var q = String(query || '').trim().toLowerCase();
    if(!q) return partiesList.slice(0, 10);

    return partiesList.filter(function(p){
      return String(p.name || '').toLowerCase().indexOf(q) !== -1 ||
             String(p.phone || '').toLowerCase().indexOf(q) !== -1 ||
             String(p.mobile || '').toLowerCase().indexOf(q) !== -1;
    }).slice(0, 15);
  }

  function renderPartyDrop(ctx, query){
    var drop = G(ctx + 'PartyDrop');
    if(!drop) return;

    var matches = searchParties(query);
    var html = '';

    if(!matches.length){
      html += '<div class="p-empty">❌ "' + esc(query) + '" পাওয়া যায়নি</div>';
    } else {
      matches.forEach(function(p){
        html += '<div class="p-item" data-party-ctx="' + ctx + '" data-party-id="' + esc(p.id) + '">';
        html += '<div class="p-name">' + esc(p.name || '') + '</div>';
        html += (p.phone || p.mobile) ? '<div class="p-phone">📞 ' + esc(p.phone || p.mobile) + '</div>' : '';
        html += '</div>';
      });
    }

    html += '<div class="p-add" data-pa-ctx="' + ctx + '">➕ নতুন সাপ্লায়ার যোগ করুন' +
            (query && query.trim() ? ' ("' + esc(query) + '")' : '') + '</div>';

    drop.innerHTML = html;
    drop.classList.add('show');
  }

  function showPartyDrop(ctx){
    var s = G(ctx + 'PartySearch');
    if(!s) return;
    activePartyContext = ctx;
    renderPartyDrop(ctx, s.value);
  }

  function hideAllPartyDrops(){
    ['m','e'].forEach(function(c){
      var d = G(c + 'PartyDrop');
      if(d) d.classList.remove('show');
    });
  }

  function selectParty(ctx, id){
    var p = partiesList.find(function(x){ return String(x.id) === String(id); });
    if(!p) return;

    if(G(ctx + 'Party')) G(ctx + 'Party').value = p.id;
    if(G(ctx + 'PartySearch')) G(ctx + 'PartySearch').style.display = 'none';
    if(G(ctx + 'PartySel')) G(ctx + 'PartySel').style.display = 'flex';
    if(G(ctx + 'PartySelName')) G(ctx + 'PartySelName').textContent = p.name || '';
    if(G(ctx + 'PartySelPhone')) G(ctx + 'PartySelPhone').textContent = (p.phone || p.mobile) ? '📞 ' + (p.phone || p.mobile) : '';

    hideAllPartyDrops();
  }

  function clearParty(ctx){
    if(G(ctx + 'Party')) G(ctx + 'Party').value = '';
    if(G(ctx + 'PartySearch')){
      G(ctx + 'PartySearch').value = '';
      G(ctx + 'PartySearch').style.display = 'block';
    }
    if(G(ctx + 'PartySel')) G(ctx + 'PartySel').style.display = 'none';
  }

  function openQuickParty(){
    var ctx = activePartyContext;
    var search = G(ctx + 'PartySearch');
    var val = search ? (search.value || '').trim() : '';

    if(G('qpName')){
      if(/^[\d\+\-\s]+$/.test(val) && val.length >= 6){
        G('qpPhone').value = val;
        G('qpName').value = '';
      } else {
        G('qpName').value = val;
        G('qpPhone').value = '';
      }
    }

    if(G('qpAddress')) G('qpAddress').value = '';
    hideBox(G('qpOk'));
    hideBox(G('qpEr'));

    if(G('qpSave')){
      G('qpSave').disabled = false;
      G('qpSave').textContent = '💾 যোগ করুন';
    }

    hideAllPartyDrops();
    if(G('quickPartyModal')) G('quickPartyModal').classList.add('show');

    setTimeout(function(){
      if(G('qpName')) G('qpName').focus();
    }, 100);
  }

  function closeQuickParty(){
    if(G('quickPartyModal')) G('quickPartyModal').classList.remove('show');
  }

  function saveQuickParty(){
    var er = G('qpEr'), ok = G('qpOk'), btn = G('qpSave');
    hideBox(er); hideBox(ok);

    var name = (G('qpName').value || '').trim();
    var phone = (G('qpPhone').value || '').trim();
    var address = (G('qpAddress').value || '').trim();

    if(!name){
      showBox(er, 'সাপ্লায়ারের নাম দিন');
      return;
    }

    if(btn){
      btn.disabled = true;
      btn.textContent = 'সেভ হচ্ছে...';
    }

    fetch(ADD_PARTY_API, {
      method:'POST',
      headers:{'Content-Type':'application/json'},
      credentials:'same-origin',
      body:JSON.stringify({
        name:name,
        phone:phone,
        address:address,
        party_type:'supplier',
        is_supplier:1
      })
    })
    .then(function(r){ return r.json(); })
    .then(function(res){
      if(res && res.success){
        showBox(ok, res.message || '✅ সাপ্লায়ার যোগ হয়েছে');

        var np = res.data || {};
        if(np.id){
          partiesList.unshift({
            id:np.id,
            name:np.name || name,
            phone:np.phone || phone
          });

          var ctx = activePartyContext;
          setTimeout(function(){
            closeQuickParty();
            selectParty(ctx, np.id);
          }, 700);
        } else {
          loadParties(function(){
            setTimeout(function(){
              closeQuickParty();
              var c = activePartyContext;
              if(G(c + 'PartySearch')){
                G(c + 'PartySearch').value = name;
                showPartyDrop(c);
              }
            }, 500);
          });
        }
      } else {
        showBox(er, '❌ ' + apiMessage(res, 'সেভ ব্যর্থ'));
      }

      if(btn){
        btn.disabled = false;
        btn.textContent = '💾 যোগ করুন';
      }
    })
    .catch(function(e){
      showBox(er, '❌ সার্ভার এরর: ' + (e.message || ''));
      if(btn){
        btn.disabled = false;
        btn.textContent = '💾 যোগ করুন';
      }
    });
  }

  function loadList(){
    var from = G('fromDate') ? G('fromDate').value : '';
    var to = G('toDate') ? G('toDate').value : '';

    var url = API_BASE + 'get_stock_list.php';
    var qs = [];

    if(from) qs.push('from_date=' + encodeURIComponent(from));
    if(to) qs.push('to_date=' + encodeURIComponent(to));
    if(qs.length) url += '?' + qs.join('&');

    var box = G('purList');
    if(box) box.innerHTML = '<div class="empty">লোড হচ্ছে...</div>';

    fetch(url, {credentials:'same-origin'})
      .then(function(r){ return r.json(); })
      .then(function(res){
        if(res && res.success){
          var rows = (res.data && res.data.stocks) ? res.data.stocks :
                     (res.stocks) ? res.stocks :
                     (res.items) ? res.items : [];

          stockList = rows;
          renderList(rows);
          updateSummary(rows);
        } else {
          if(box) box.innerHTML = '<div class="empty">❌ ' + apiMessage(res, 'লোড করা যায়নি') + '</div>';
        }
      })
      .catch(function(e){
        if(box) box.innerHTML = '<div class="empty">❌ সার্ভার এরর: ' + (e.message || '') + '</div>';
      });
  }

  function renderList(rows){
    var box = G('purList');
    if(!box) return;

    if(!rows || !rows.length){
      box.innerHTML = '<div class="empty">কোনো স্টক পাওয়া যায়নি</div>';
      return;
    }

    var html = '';

    rows.forEach(function(r){
      var id = getStockId(r);
      var itemName = getItemName(r);
      var supplier = r.supplier_name || '';

      if(!supplier && r.supplier_id){
        var p = partiesList.find(function(x){ return String(x.id) === String(r.supplier_id); });
        if(p) supplier = p.name;
      }

      var karat = r.karat || r.purity || '22K';
      var kcls = KARAT_CLASS[karat] || 'k-other';

      var gross = getTotalWeight(r);
      var pure = getPureWeight(r);
      var pcs = getTotalPcs(r);
      var availPcs = getAvailablePcs(r);
      var availW = getAvailableWeight(r);
      var amt = num(r.total_amount || r.amount);

      var gW = gramToWeight(gross);
      var pW = gramToWeight(pure);

      var gBr = bn(gW.vori) + 'ভ ' + bn(gW.ana) + 'আ ' + bn(gW.roti) + 'র ' + bn(gW.point) + 'প';
      var pBr = bn(pW.vori) + 'ভ ' + bn(pW.ana) + 'আ ' + bn(pW.roti) + 'র ' + bn(pW.point) + 'প';

      var used = isUsedStock(r);

      html += '<div class="pur-card">';
      html += '<div class="pur-top"><div>';
      html += '<div class="pur-name">' + esc(itemName) + '</div>';
      if(supplier) html += '<div class="pur-supplier">🏢 ' + esc(supplier) + '</div>';
      html += '<div class="pur-date">📅 ' + bnDate(r.stock_date) + '</div>';
      html += '</div><span class="pur-karat ' + kcls + '">' + esc(karat) + '</span></div>';

      html += '<div class="pur-details">';
      html += '<div class="pur-detail"><div class="dl">পিস</div><div class="dv">' + bn(pcs) + '</div></div>';
      html += '<div class="pur-detail"><div class="dl">গ্রস</div><div class="dv">' + bn(gross.toFixed(3)) + 'g</div><div class="ds">' + gBr + '</div></div>';
      html += '<div class="pur-detail"><div class="dl">বিশুদ্ধ</div><div class="dv">' + bn(pure.toFixed(3)) + 'g</div><div class="ds">' + pBr + '</div></div>';
      html += '</div>';

      html += '<div style="padding:6px 0;font-size:13px;">';
      if(availPcs > 0){
        html += '<div style="color:#F5B800;font-weight:700;">🏷 বারকোড বাকি: ' + bn(availPcs) + ' পিস | ' + bn(availW.toFixed(3)) + 'g</div>';
      } else {
        html += '<div style="color:#22C55E;font-weight:700;">✅ সব বারকোড তৈরি</div>';
      }
      if(used){
        html += '<div style="color:#5C7DA8;font-size:11px;margin-top:3px;">Used/Transferred stock — delete বন্ধ</div>';
      }
      html += '</div>';

      html += '<div class="pur-bottom">';
      html += '<div class="pur-amount">' + tk(amt) + '</div>';
      html += '<div class="pur-actions">';
      html += '<button class="edit-btn" data-edit-id="' + esc(id) + '">✏️ এডিট</button>';

      if(availPcs > 0){
        html += '<button class="barcode-btn" data-barcode-id="' + esc(id) + '" style="background:#F5B800;color:#000;border:none;border-radius:8px;padding:8px 12px;font-weight:800;cursor:pointer;font-size:13px;font-family:inherit;">🏷 বারকোড</button>';
      }

      if(!used){
        html += '<button class="del-btn" data-del-id="' + esc(id) + '" data-del-name="' + esc(itemName) + '" data-del-amt="' + esc(tk(amt)) + '">🗑 মুছুন</button>';
      } else {
        html += '<button class="del-btn" disabled style="opacity:.35;cursor:not-allowed;">🔒 মুছা যাবে না</button>';
      }

      html += '</div></div></div>';
    });

    box.innerHTML = html;
  }

  function updateSummary(rows){
    var today = todayStr();
    var cnt = 0, amt = 0, grs = 0, pcs = 0;

    rows.forEach(function(r){
      if(String(r.stock_date || '').substring(0, 10) === today){
        cnt++;
        amt += num(r.total_amount || r.amount);
        grs += getTotalWeight(r);
        pcs += getTotalPcs(r);
      }
    });

    if(G('sumEntries')) G('sumEntries').textContent = bn(cnt);
    if(G('sumAmount')) G('sumAmount').textContent = bn(Math.round(amt).toLocaleString('en-IN'));
    if(G('sumGross')) G('sumGross').textContent = bn(grs.toFixed(2));
    if(G('sumPieces')) G('sumPieces').textContent = bn(pcs);

    var grsCard = G('sumGross');
    if(grsCard && grsCard.closest){
      var gW = gramToWeight(grs);
      var br = bn(gW.vori) + 'ভ ' + bn(gW.ana) + 'আ ' + bn(gW.roti) + 'র ' + bn(gW.point) + 'প';
      var pc = grsCard.closest('.sum-card');
      if(pc){
        var sd = pc.querySelector('.sum-sub');
        if(sd) sd.textContent = br;
      }
    }
  }

  function mDoWeight(){
    var gram = weightToGram(G('wVori') ? G('wVori').value : 0, G('wAna') ? G('wAna').value : 0, G('wRoti') ? G('wRoti').value : 0, G('wPoint') ? G('wPoint').value : 0);

    if(G('wGram')) G('wGram').textContent = bn(gram.toFixed(3));
    if(G('wVoriShow')) G('wVoriShow').textContent = bn(G('wVori').value || 0);
    if(G('wAnaShow')) G('wAnaShow').textContent = bn(G('wAna').value || 0);
    if(G('wRotiShow')) G('wRotiShow').textContent = bn(G('wRoti').value || 0);
    if(G('wPointShow')) G('wPointShow').textContent = bn(G('wPoint').value || 0);

    mDoCalc();
  }

  function mDoCalc(){
    var gross = weightToGram(G('wVori') ? G('wVori').value : 0, G('wAna') ? G('wAna').value : 0, G('wRoti') ? G('wRoti').value : 0, G('wPoint') ? G('wPoint').value : 0);
    var karat = G('mKarat') ? G('mKarat').value : '22K';
    var ratio = karatRatio(karat);
    var pure = gross * (ratio / 100);
    var rateVori = num(G('mRate') ? G('mRate').value : 0);
    var rateG = rateVori / BHARI;
    var total = pure * rateG;
    var pieces = intNum(G('mPieces') ? G('mPieces').value : 1) || 1;
    var wpp = pieces > 0 ? gross / pieces : 0;

    if(G('cRatio')) G('cRatio').textContent = bn(ratio.toFixed(2)) + '%';
    if(G('cGross')) G('cGross').textContent = bn(gross.toFixed(3)) + ' গ্রাম';
    if(G('cPure')) G('cPure').textContent = bn(pure.toFixed(3)) + ' গ্রাম';
    if(G('cRateG')) G('cRateG').textContent = tk(rateG.toFixed(0)) + '/গ্রাম';
    if(G('cWpp')) G('cWpp').textContent = bn(wpp.toFixed(3)) + ' গ্রাম/পিস';
    if(G('cTotal')) G('cTotal').textContent = tk(Math.round(total));
  }

  function eDoCalc(){
    var gross = weightToGram(G('eVori') ? G('eVori').value : 0, G('eAna') ? G('eAna').value : 0, G('eRoti') ? G('eRoti').value : 0, G('ePoint') ? G('ePoint').value : 0);
    var karat = G('eKarat') ? G('eKarat').value : '22K';
    var ratio = karatRatio(karat);
    var pure = gross * (ratio / 100);
    var rateVori = num(G('eRate') ? G('eRate').value : 0);
    var total = pure * (rateVori / BHARI);

    if(G('eGram')) G('eGram').textContent = bn(gross.toFixed(3));
    if(G('eCRatio')) G('eCRatio').textContent = bn(ratio.toFixed(2)) + '%';
    if(G('eCGross')) G('eCGross').textContent = bn(gross.toFixed(3)) + ' গ্রাম';
    if(G('eCPure')) G('eCPure').textContent = bn(pure.toFixed(3)) + ' গ্রাম';
    if(G('eCTotal')) G('eCTotal').textContent = tk(Math.round(total));
  }

  function openSingleModal(){
    if(G('mDate')) G('mDate').value = todayStr();
    if(G('mItemName')) G('mItemName').value = '';
    if(G('mKarat')) G('mKarat').value = '22K';
    if(G('mPieces')) G('mPieces').value = '1';
    if(G('mLocation')) G('mLocation').value = '1';
    if(G('wVori')) G('wVori').value = '';
    if(G('wAna')) G('wAna').value = '';
    if(G('wRoti')) G('wRoti').value = '';
    if(G('wPoint')) G('wPoint').value = '';
    if(G('mRate')) G('mRate').value = '';
    if(G('mPayment')) G('mPayment').value = '1';
    if(G('mNote')) G('mNote').value = '';

    hideBox(G('mOk'));
    hideBox(G('mEr'));

    if(G('mBtn')){
      G('mBtn').disabled = false;
      G('mBtn').textContent = '💾 স্টক সেভ করুন';
    }

    clearParty('m');
    loadParties();
    loadAccounts();
    mDoWeight();
    activePartyContext = 'm';

    if(G('purModal')) G('purModal').classList.add('show');
  }

  function closeSingleModal(){
    if(G('purModal')) G('purModal').classList.remove('show');
    hideAllPartyDrops();
  }

  function saveSingle(){
    var btn = G('mBtn'), er = G('mEr'), ok = G('mOk');
    hideBox(er); hideBox(ok);

    var gross = weightToGram(G('wVori').value, G('wAna').value, G('wRoti').value, G('wPoint').value);
    var karat = G('mKarat').value || '22K';
    var ratio = karatRatio(karat);
    var pure = gross * (ratio / 100);
    var rate = num(G('mRate').value);
    var total = pure * (rate / BHARI);

    var itemName = (G('mItemName').value || '').trim();
    var partyId = intNum(G('mParty').value) || null;
    var pieces = intNum(G('mPieces').value) || 1;
    var locationId = intNum(G('mLocation').value) || 1;
    var payId = intNum(G('mPayment').value) || 1;
    var cashAccId = intNum(G('mCashAcc').value) || null;
    var note = (G('mNote').value || '').trim();

    if(!itemName){ showBox(er, 'আইটেমের নাম দিন'); return; }
    if(gross <= 0){ showBox(er, 'ওজন দিন'); return; }
    if(rate > 0 && total > 0 && !cashAccId){ showBox(er, 'ক্যাশ অ্যাকাউন্ট বাছাই করুন'); return; }

    var payload = {
      stock_date: G('mDate').value || todayStr(),
      item_name: itemName,
      category: itemName,
      party_id: partyId,
      supplier_id: partyId,
      karat: karat,
      total_pieces: pieces,
      total_pcs: pieces,
      location_id: locationId,
      total_weight_gram: parseFloat(gross.toFixed(3)),
      pure_weight_gram: parseFloat(pure.toFixed(3)),
      rate_per_vori: rate,
      total_amount: parseFloat(total.toFixed(2)),
      payment_method_id: payId,
      cash_account_id: cashAccId,
      note: note
    };

    if(btn){
      btn.disabled = true;
      btn.textContent = 'সেভ হচ্ছে...';
    }

    fetch(API_BASE + 'add_stock.php', {
      method:'POST',
      headers:{'Content-Type':'application/json'},
      credentials:'same-origin',
      body:JSON.stringify(payload)
    })
    .then(function(r){ return r.json(); })
    .then(function(res){
      if(res && res.success){
        showBox(ok, res.message || '✅ সফল');
        setTimeout(function(){
          closeSingleModal();
          loadList();
          loadAccounts();
        }, 1000);
      } else {
        showBox(er, '❌ ' + apiMessage(res, 'সেভ ব্যর্থ'));
      }

      if(btn){
        btn.disabled = false;
        btn.textContent = '💾 স্টক সেভ করুন';
      }
    })
    .catch(function(e){
      showBox(er, '❌ সার্ভার এরর: ' + (e.message || ''));
      if(btn){
        btn.disabled = false;
        btn.textContent = '💾 স্টক সেভ করুন';
      }
    });
  }

  function fillEditModal(stock){
    if(G('eId')) G('eId').value = stock.id || stock.stock_id;
    if(G('eDate')) G('eDate').value = String(stock.stock_date || '').substring(0, 10);
    if(G('eItemName')) G('eItemName').value = getItemName(stock);
    if(G('eKarat')) G('eKarat').value = stock.karat || stock.purity || '22K';
    if(G('ePieces')) G('ePieces').value = stock.total_pcs || 1;
    if(G('eLocation')) G('eLocation').value = stock.location_id || stock.stock_location_id || 1;
    if(G('eRate')) G('eRate').value = stock.rate_per_vori || '';
    if(G('eNote')) G('eNote').value = stock.note || '';

    var w = gramToWeight(getTotalWeight(stock));
    if(G('eVori')) G('eVori').value = w.vori || '';
    if(G('eAna')) G('eAna').value = w.ana || '';
    if(G('eRoti')) G('eRoti').value = w.roti || '';
    if(G('ePoint')) G('ePoint').value = w.point || '';

    clearParty('e');

    if(stock.supplier_id){
      if(partiesList.length === 0){
        loadParties(function(){ selectParty('e', stock.supplier_id); });
      } else {
        selectParty('e', stock.supplier_id);
      }
    }

    loadAccounts();

    if(G('ePayment')) G('ePayment').value = stock.payment_method_id || '1';

    setTimeout(function(){
      if(G('eCashAcc') && stock.cash_account_id) G('eCashAcc').value = stock.cash_account_id;
    }, 300);

    eDoCalc();
  }

  function openEditModal(id){
    hideBox(G('eOk'));
    hideBox(G('eEr'));

    if(G('eSaveBtn')){
      G('eSaveBtn').disabled = false;
      G('eSaveBtn').textContent = '💾 আপডেট করুন';
    }

    if(G('eUpdatePayCheck')){
      G('eUpdatePayCheck').classList.remove('on');
      G('eUpdatePayCheck').innerHTML = '';
    }

    if(G('ePaySection')) G('ePaySection').classList.remove('show');

    fetch(API_BASE + 'get_stock_details.php?id=' + encodeURIComponent(id), {credentials:'same-origin'})
      .then(function(r){ return r.json(); })
      .then(function(res){
        if(res && res.success){
          var stock = res.data || res.stock;
          fillEditModal(stock);
          activePartyContext = 'e';
          if(G('editModal')) G('editModal').classList.add('show');
        } else {
          alert('❌ ' + apiMessage(res, 'স্টক বিস্তারিত পাওয়া যায়নি'));
        }
      })
      .catch(function(e){
        alert('❌ সার্ভার এরর: ' + (e.message || ''));
      });
  }

  function closeEditModal(){
    if(G('editModal')) G('editModal').classList.remove('show');
    hideAllPartyDrops();
  }

  function togglePaySection(){
    var chk = G('eUpdatePayCheck'), sec = G('ePaySection');
    if(!chk || !sec) return;

    if(chk.classList.contains('on')){
      chk.classList.remove('on');
      chk.innerHTML = '';
      sec.classList.remove('show');
    } else {
      chk.classList.add('on');
      chk.innerHTML = '✓';
      sec.classList.add('show');
    }
  }

  function saveEdit(){
    var btn = G('eSaveBtn'), er = G('eEr'), ok = G('eOk');
    hideBox(er); hideBox(ok);

    var id = intNum(G('eId').value);
    if(!id){ showBox(er, 'ID পাওয়া যায়নি'); return; }

    var gross = weightToGram(G('eVori').value, G('eAna').value, G('eRoti').value, G('ePoint').value);
    var karat = G('eKarat').value || '22K';
    var ratio = karatRatio(karat);
    var pure = gross * (ratio / 100);
    var rate = num(G('eRate').value);
    var total = pure * (rate / BHARI);

    var itemName = (G('eItemName').value || '').trim();
    var partyId = intNum(G('eParty').value) || null;
    var pieces = intNum(G('ePieces').value) || 1;
    var locationId = intNum(G('eLocation').value) || 1;
    var note = (G('eNote').value || '').trim();

    if(!itemName){ showBox(er, 'আইটেমের নাম দিন'); return; }
    if(gross <= 0){ showBox(er, 'ওজন দিন'); return; }

    var updatePay = G('eUpdatePayCheck') && G('eUpdatePayCheck').classList.contains('on');
    var payId = updatePay ? (intNum(G('ePayment').value) || 1) : null;
    var cashAccId = updatePay ? (intNum(G('eCashAcc').value) || null) : null;

    if(updatePay && total > 0 && !cashAccId){
      showBox(er, 'ক্যাশ অ্যাকাউন্ট বাছাই করুন');
      return;
    }

    var payload = {
      id:id,
      stock_date:G('eDate').value || todayStr(),
      item_name:itemName,
      category:itemName,
      party_id:partyId,
      supplier_id:partyId,
      karat:karat,
      total_pieces:pieces,
      total_pcs:pieces,
      location_id:locationId,
      total_weight_gram:parseFloat(gross.toFixed(3)),
      pure_weight_gram:parseFloat(pure.toFixed(3)),
      rate_per_vori:rate,
      total_amount:parseFloat(total.toFixed(2)),
      note:note,
      update_payment:updatePay,
      payment_method_id:payId,
      cash_account_id:cashAccId
    };

    if(btn){
      btn.disabled = true;
      btn.textContent = 'আপডেট হচ্ছে...';
    }

    fetch(API_BASE + 'update_stock.php', {
      method:'POST',
      headers:{'Content-Type':'application/json'},
      credentials:'same-origin',
      body:JSON.stringify(payload)
    })
    .then(function(r){ return r.json(); })
    .then(function(res){
      if(res && res.success){
        showBox(ok, res.message || '✅ আপডেট হয়েছে');
        setTimeout(function(){
          closeEditModal();
          loadList();
          loadAccounts();
        }, 1000);
      } else {
        showBox(er, '❌ ' + apiMessage(res, 'আপডেট ব্যর্থ'));
      }

      if(btn){
        btn.disabled = false;
        btn.textContent = '💾 আপডেট করুন';
      }
    })
    .catch(function(e){
      showBox(er, '❌ সার্ভার এরর: ' + (e.message || ''));
      if(btn){
        btn.disabled = false;
        btn.textContent = '💾 আপডেট করুন';
      }
    });
  }

  function deleteStock(id, name, amt){
    var reason = prompt(
      'স্টক delete/void করবেন?\n\nআইটেম: ' + name + '\nপরিমাণ: ' + amt + '\n\nকারণ লিখুন:',
      'ভুল এন্ট্রি'
    );

    if(reason === null) return;
    reason = String(reason || '').trim();
    if(!reason) reason = 'ভুল এন্ট্রি';

    fetch(API_BASE + 'delete_stock.php', {
      method:'POST',
      headers:{'Content-Type':'application/json'},
      credentials:'same-origin',
      body:JSON.stringify({id:id, reason:reason})
    })
    .then(function(r){ return r.json(); })
    .then(function(res){
      if(res && res.success){
        alert('✅ ' + (res.message || 'delete হয়েছে'));
        loadList();
        loadAccounts();
      } else {
        alert('❌ ' + apiMessage(res, 'delete ব্যর্থ'));
      }
    })
    .catch(function(e){
      alert('❌ সার্ভার এরর: ' + (e.message || ''));
    });
  }

  function bcItemGram(item){
    return weightToGram(item.vori, item.ana, item.roti, item.point);
  }

  function injectBarcodeModal(){
    if(G('barcodeCreateModal')) return;

    var div = document.createElement('div');
    div.id = 'barcodeCreateModal';
    div.style.cssText = 'position:fixed;inset:0;background:rgba(4,8,18,.97);z-index:99999;display:none;flex-direction:column;overflow:hidden;';

    div.innerHTML =
      '<div style="background:#0F1A30;padding:14px 16px;border-bottom:1.5px solid #2A3D63;flex-shrink:0;display:flex;justify-content:space-between;align-items:center;">' +
        '<div style="color:#F5B800;font-size:17px;font-weight:800;">🏷 বারকোড তৈরি</div>' +
        '<button id="bcCancelBtn" style="background:transparent;border:0;color:#8B95A7;font-size:30px;cursor:pointer;line-height:1;padding:0 6px;">×</button>' +
      '</div>' +
      '<div id="bcFormBody" style="flex:1;overflow-y:auto;padding:14px 16px 24px;-webkit-overflow-scrolling:touch;"></div>' +
      '<div style="background:#0F1A30;padding:12px 16px;border-top:1.5px solid #2A3D63;flex-shrink:0;">' +
        '<div id="bcError" style="display:none;background:rgba(239,68,68,.12);color:#EF4444;border-radius:8px;padding:10px 12px;margin-bottom:10px;font-size:13px;font-weight:700;"></div>' +
        '<div style="display:flex;gap:10px;">' +
          '<button id="bcCancelBtn2" style="flex:1;background:#142547;color:#E5E9F0;border:1.5px solid #2A3D63;border-radius:10px;padding:12px;font-size:14px;font-weight:700;cursor:pointer;font-family:inherit;">বাতিল</button>' +
          '<button id="bcSaveBtn" style="flex:2;background:#22C55E;color:#000;border:none;border-radius:10px;padding:12px;font-size:14px;font-weight:900;cursor:pointer;font-family:inherit;">✅ বারকোড সেভ করুন</button>' +
        '</div>' +
      '</div>';

    document.body.appendChild(div);
  }

  function renderBarcodeForm(){
    var fb = G('bcFormBody');
    if(!fb || !activeBarcodeStock) return;

    var s = activeBarcodeStock;
    var availPcs = getAvailablePcs(s);
    var availW = getAvailableWeight(s);
    var productName = getItemName(s);
    var supplier = s.supplier_name || '';

    if(!supplier && s.supplier_id){
      var p = partiesList.find(function(x){ return String(x.id) === String(s.supplier_id); });
      if(p) supplier = p.name;
    }

    var sW = gramToWeight(availW);
    var html = '';

    html += '<div style="background:#080F1E;border-radius:12px;padding:14px;margin-bottom:16px;border:1px solid #1E2D4D;font-size:13px;">';
    if(supplier) html += '<div style="color:#8B95A7;margin-bottom:4px;">সাপ্লায়ার <strong style="color:#E5E9F0;">' + esc(supplier) + '</strong></div>';
    html += '<div style="color:#8B95A7;margin-bottom:6px;">স্টক নাম <strong style="color:#F5B800;font-size:15px;">' + esc(productName) + '</strong></div>';
    html += '<div style="display:flex;justify-content:space-between;margin-bottom:4px;">';
    html += '<span style="color:#8B95A7;">স্টক ক্যারেট <strong style="color:#E5E9F0;">' + esc(s.karat || '22K') + '</strong></span>';
    html += '<span style="color:#8B95A7;">বাকি <strong style="color:#F5B800;">' + bn(availPcs) + ' পিস</strong></span>';
    html += '</div>';
    html += '<div style="color:#8B95A7;">Available weight <span style="color:#E5E9F0;">' + bn(availW.toFixed(3)) + 'g | ' + bn(sW.vori) + ' ভরি ' + bn(sW.ana) + ' আনা ' + bn(sW.roti) + ' রতি ' + bn(sW.point) + ' পয়েন্ট</span></div>';
    html += '</div>';

    bcItems.forEach(function(item, i){
      var gram = bcItemGram(item);
      var wObj = gramToWeight(gram);

      var categoryForSelect = item.category || item.name;
      var catVal = itemCategoryValue(categoryForSelect);
      var customDisplay = catVal === 'অন্যান্য' ? 'block' : 'none';
      var customName = catVal === 'অন্যান্য' ? (item.name || '') : '';

      html += '<div style="background:#0F1A30;border-radius:12px;padding:14px;margin-bottom:12px;border:1.5px solid #2A3D63;">';
      html += '<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;">';
      html += '<div style="color:#F5B800;font-size:14px;font-weight:800;">বারকোড আইটেম ' + bn(i + 1) + '</div>';
      if(bcItems.length > 1){
        html += '<button class="bc-remove" data-bc-idx="' + i + '" style="background:transparent;color:#EF4444;border:1px solid rgba(239,68,68,.3);border-radius:6px;padding:4px 10px;font-size:12px;cursor:pointer;font-weight:700;font-family:inherit;">× বাদ</button>';
      }
      html += '</div>';

      html += '<div style="margin-bottom:10px;"><label style="display:block;font-size:11px;color:#8B95A7;margin-bottom:5px;font-weight:700;">পণ্যের ক্যাটাগরি</label>';
      html += '<select class="bc-item-category" data-bc-idx="' + i + '" style="width:100%;background:#080F1E;border:1.5px solid #1E2D4D;border-radius:8px;color:#E5E9F0;padding:10px 12px;font-size:15px;font-family:inherit;outline:none;">';
      html += itemCategoryOptions(categoryForSelect);
      html += '</select></div>';

      html += '<div class="bc-custom-name-wrap" data-bc-custom-wrap="' + i + '" style="display:' + customDisplay + ';margin-bottom:10px;">';
      html += '<label style="display:block;font-size:11px;color:#8B95A7;margin-bottom:5px;font-weight:700;">অন্যান্য পণ্যের নাম</label>';
      html += '<input class="bc-item-name" data-bc-idx="' + i + '" value="' + esc(customName) + '" style="width:100%;background:#080F1E;border:1.5px solid #1E2D4D;border-radius:8px;color:#E5E9F0;padding:10px 12px;font-size:15px;font-family:inherit;outline:none;" placeholder="যেমন: মাথার টিকলি">';
      html += '</div>';

      html += '<div style="margin-bottom:10px;"><label style="display:block;font-size:11px;color:#8B95A7;margin-bottom:5px;font-weight:700;">ক্যারেট</label>';
      html += '<select class="bc-item-karat" data-bc-idx="' + i + '" style="width:100%;background:#080F1E;border:1.5px solid #1E2D4D;border-radius:8px;color:#E5E9F0;padding:10px 12px;font-size:15px;font-family:inherit;outline:none;">';
      ['24K','22K','21K','18K'].forEach(function(k){
        html += '<option value="' + k + '"' + (item.karat === k ? ' selected' : '') + '>' + k + '</option>';
      });
      html += '</select></div>';

      html += '<div style="display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin-bottom:10px;">';
      [['vori','ভরি'],['ana','আনা'],['roti','রতি'],['point','পয়েন্ট']].forEach(function(f){
        html += '<div style="display:flex;flex-direction:column;align-items:center;">';
        html += '<input class="bc-item-w" data-bc-idx="' + i + '" data-bc-field="' + f[0] + '" type="number" min="0" step="1" value="' + esc(item[f[0]] || '') + '" placeholder="0" style="width:100%;background:#080F1E;border:1.5px solid #1E2D4D;border-radius:8px;color:#E5E9F0;padding:9px 4px;font-size:16px;text-align:center;font-family:inherit;outline:none;">';
        html += '<span style="font-size:10px;color:#8B95A7;margin-top:4px;font-weight:600;">' + f[1] + '</span>';
        html += '</div>';
      });
      html += '</div>';

      html += '<div style="margin-bottom:10px;"><input class="bc-item-note" data-bc-idx="' + i + '" value="' + esc(item.note || '') + '" style="width:100%;background:#080F1E;border:1.5px solid #1E2D4D;border-radius:8px;color:#8B95A7;padding:10px 12px;font-size:14px;font-family:inherit;outline:none;" placeholder="ঐচ্ছিক নোট"></div>';

      html += '<div data-bc-wdisplay="' + i + '" style="background:#080F1E;border-radius:8px;padding:10px 12px;font-size:13px;color:#E5E9F0;border:1px solid #1E2D4D;">ওজন: <strong style="color:#F5B800;">' + bn(gram.toFixed(3)) + 'g</strong> | ' + bn(wObj.vori) + ' ভরি ' + bn(wObj.ana) + ' আনা ' + bn(wObj.roti) + ' রতি ' + bn(wObj.point) + ' পয়েন্ট</div>';
      html += '</div>';
    });

    if(bcItems.length < availPcs){
      html += '<button id="bcAddItem" style="width:100%;background:#142547;color:#F5B800;border:1.5px dashed #2A3D63;border-radius:10px;padding:13px;font-size:14px;font-weight:800;cursor:pointer;font-family:inherit;margin-bottom:14px;">+ আরেকটি বারকোড যোগ করুন</button>';
    }

    var totalBcG = bcItems.reduce(function(sum, it){ return sum + bcItemGram(it); }, 0);
    var totalBcW = gramToWeight(totalBcG);

    html += '<div style="background:#080F1E;border-radius:12px;padding:14px;border:1px solid #1E2D4D;">';
    html += '<div style="display:flex;justify-content:space-between;padding:7px 0;border-bottom:1px dashed #1E2D4D;font-size:14px;"><span style="color:#8B95A7;">এইবার পিস</span><strong data-bc-sum="pcs" style="color:#E5E9F0;">' + bn(bcItems.length) + ' পিস</strong></div>';
    html += '<div style="display:flex;justify-content:space-between;padding:7px 0;border-bottom:1px dashed #1E2D4D;font-size:14px;"><span style="color:#8B95A7;">এইবার ওজন</span><strong data-bc-sum="gram" style="color:#F5B800;">' + bn(totalBcG.toFixed(3)) + 'g</strong></div>';
    html += '<div style="display:flex;justify-content:space-between;padding:7px 0;border-bottom:1px dashed #1E2D4D;font-size:14px;"><span style="color:#8B95A7;">ভাঙা</span><strong data-bc-sum="varp" style="color:#E5E9F0;">' + bn(totalBcW.vori) + ' ভরি ' + bn(totalBcW.ana) + ' আনা ' + bn(totalBcW.roti) + ' রতি ' + bn(totalBcW.point) + ' পয়েন্ট</strong></div>';
    html += '<div style="display:flex;justify-content:space-between;padding:7px 0;font-size:14px;"><span style="color:#8B95A7;">Available</span><strong style="color:#E5E9F0;">' + bn(availW.toFixed(3)) + 'g</strong></div>';
    html += '</div>';

    fb.innerHTML = html;
    bindBarcodeInputs();
  }

  function updateBcSummaryRows(){
    var totalBcG = bcItems.reduce(function(sum, it){ return sum + bcItemGram(it); }, 0);
    var totalBcW = gramToWeight(totalBcG);

    document.querySelectorAll('[data-bc-sum]').forEach(function(el){
      var type = el.getAttribute('data-bc-sum');
      if(type === 'pcs') el.textContent = bn(bcItems.length) + ' পিস';
      if(type === 'gram') el.textContent = bn(totalBcG.toFixed(3)) + 'g';
      if(type === 'varp') el.textContent = bn(totalBcW.vori) + ' ভরি ' + bn(totalBcW.ana) + ' আনা ' + bn(totalBcW.roti) + ' রতি ' + bn(totalBcW.point) + ' পয়েন্ট';
    });
  }

  function bindBarcodeInputs(){
    document.querySelectorAll('.bc-item-category').forEach(function(sel){
      sel.addEventListener('change', function(){
        var i = intNum(sel.dataset.bcIdx);
        if(!bcItems[i]) return;

        if(sel.value === 'অন্যান্য'){
          bcItems[i].category = 'অন্যান্য';
          bcItems[i].name = '';
        } else {
          bcItems[i].category = sel.value;
          bcItems[i].name = sel.value;
        }

        renderBarcodeForm();
      });
    });

    document.querySelectorAll('.bc-item-name').forEach(function(inp){
      inp.addEventListener('input', function(){
        var i = intNum(inp.dataset.bcIdx);
        if(bcItems[i]){
          bcItems[i].name = inp.value;
          bcItems[i].category = 'অন্যান্য';
        }
      });
    });

    document.querySelectorAll('.bc-item-karat').forEach(function(sel){
      sel.addEventListener('change', function(){
        var i = intNum(sel.dataset.bcIdx);
        if(bcItems[i]) bcItems[i].karat = sel.value;
      });
    });

    document.querySelectorAll('.bc-item-w').forEach(function(inp){
      inp.addEventListener('input', function(){
        var i = intNum(inp.dataset.bcIdx);
        if(bcItems[i]) bcItems[i][inp.dataset.bcField] = inp.value;

        var wDisp = document.querySelector('[data-bc-wdisplay="' + i + '"]');
        if(wDisp && bcItems[i]){
          var g = bcItemGram(bcItems[i]);
          var wO = gramToWeight(g);
          wDisp.innerHTML = 'ওজন: <strong style="color:#F5B800;">' + bn(g.toFixed(3)) + 'g</strong> | ' + bn(wO.vori) + ' ভরি ' + bn(wO.ana) + ' আনা ' + bn(wO.roti) + ' রতি ' + bn(wO.point) + ' পয়েন্ট';
        }

        updateBcSummaryRows();
      });
    });

    document.querySelectorAll('.bc-item-note').forEach(function(inp){
      inp.addEventListener('input', function(){
        var i = intNum(inp.dataset.bcIdx);
        if(bcItems[i]) bcItems[i].note = inp.value;
      });
    });

    document.querySelectorAll('.bc-remove').forEach(function(btn){
      btn.addEventListener('click', function(){
        var i = intNum(btn.dataset.bcIdx);
        bcItems.splice(i, 1);
        if(!bcItems.length) addBcItem();
        renderBarcodeForm();
      });
    });

    var addBtn = G('bcAddItem');
    if(addBtn) addBtn.addEventListener('click', addBcItem);
  }

  function addBcItem(){
    if(!activeBarcodeStock) return;

    var availPcs = getAvailablePcs(activeBarcodeStock);
    var availW = getAvailableWeight(activeBarcodeStock);

    if(bcItems.length >= availPcs) return;

    var avg = availPcs > 0 ? availW / availPcs : 0;
    var w = gramToWeight(avg);
    var defaultName = getItemName(activeBarcodeStock);

    bcItems.push({
      name: itemCategoryValue(defaultName) === 'অন্যান্য' ? '' : itemCategoryValue(defaultName),
      category: itemCategoryValue(defaultName),
      karat:activeBarcodeStock.karat || '22K',
      vori:w.vori || '',
      ana:w.ana || '',
      roti:w.roti || '',
      point:w.point || '',
      note:''
    });

    renderBarcodeForm();

    var fb = G('bcFormBody');
    if(fb) setTimeout(function(){ fb.scrollTop = fb.scrollHeight; }, 50);
  }

  function openBarcodeModal(stockId){
    var stock = stockList.find(function(x){ return String(getStockId(x)) === String(stockId); });
    if(!stock){
      alert('স্টক পাওয়া যায়নি');
      return;
    }

    var availPcs = getAvailablePcs(stock);
    var availW = getAvailableWeight(stock);

    if(availPcs <= 0 || availW <= 0){
      alert('এই stock থেকে barcode তৈরি করার মতো available pcs/weight নেই');
      return;
    }

    activeBarcodeStock = stock;

    var avgG = availW / availPcs;
    var avgW = gramToWeight(avgG);
    var defaultName = getItemName(stock);
    var defaultCat = itemCategoryValue(defaultName);

    bcItems = [{
      name: defaultCat === 'অন্যান্য' ? '' : defaultCat,
      category: defaultCat,
      karat:stock.karat || '22K',
      vori:avgW.vori || '',
      ana:avgW.ana || '',
      roti:avgW.roti || '',
      point:avgW.point || '',
      note:''
    }];

    hideBox(G('bcError'));

    if(G('bcSaveBtn')){
      G('bcSaveBtn').disabled = false;
      G('bcSaveBtn').textContent = '✅ বারকোড সেভ করুন';
    }

    renderBarcodeForm();

    var modal = G('barcodeCreateModal');
    if(modal) modal.style.display = 'flex';

    var fb = G('bcFormBody');
    if(fb) fb.scrollTop = 0;
  }

  function closeBarcodeModal(){
    var modal = G('barcodeCreateModal');
    if(modal) modal.style.display = 'none';
    activeBarcodeStock = null;
    bcItems = [];
  }

  function saveBarcodeTransfer(){
    if(!activeBarcodeStock) return;

    var er = G('bcError');
    var btn = G('bcSaveBtn');
    hideBox(er);

    var availPcs = getAvailablePcs(activeBarcodeStock);
    var availW = getAvailableWeight(activeBarcodeStock);
    var fallbackName = getItemName(activeBarcodeStock);

    if(bcItems.length <= 0){
      showBox(er, 'কমপক্ষে ১টি barcode item দিন');
      return;
    }

    if(bcItems.length > availPcs){
      showBox(er, 'সর্বোচ্চ ' + bn(availPcs) + ' পিস barcode করা যাবে');
      return;
    }

    var totalG = 0;

    for(var i = 0; i < bcItems.length; i++){
      var itemName = getBarcodeItemName(bcItems[i], fallbackName);
      if(!itemName || itemName === 'অন্যান্য'){
        showBox(er, 'Barcode item ' + bn(i + 1) + ' এর পণ্যের নাম/ক্যাটাগরি দিন');
        return;
      }

      var g = bcItemGram(bcItems[i]);
      if(g <= 0){
        showBox(er, 'Barcode item ' + bn(i + 1) + ' এর ওজন দিন');
        return;
      }
      totalG += g;
    }

    totalG = parseFloat(totalG.toFixed(3));

    if(totalG > availW + 0.001){
      showBox(er, 'মোট barcode ওজন available stock থেকে বেশি');
      return;
    }

    if(btn){
      btn.disabled = true;
      btn.textContent = 'তৈরি হচ্ছে...';
    }

    var payload = {
      stock_id:getStockId(activeBarcodeStock),
      pieces:bcItems.map(function(it){
        var g = bcItemGram(it);
        var karat = it.karat || activeBarcodeStock.karat || '22K';
        var pure = pureFromGross(g, karat);
        var itemName = getBarcodeItemName(it, fallbackName);
        var itemCat = getBarcodeCategory(it, fallbackName);

        return {
          name:itemName,
          item_name:itemName,
          product_name:itemName,
          category:itemCat,
          item_category:itemCat,
          karat:karat,
          gross_weight_gram:parseFloat(g.toFixed(3)),
          pure_weight_gram:parseFloat(pure.toFixed(3)),
          vori:it.vori || 0,
          ana:it.ana || 0,
          roti:it.roti || 0,
          rati:it.roti || 0,
          point:it.point || 0,
          note:it.note || ''
        };
      })
    };

    fetch(API_BASE + 'transfer_to_barcode.php', {
      method:'POST',
      headers:{'Content-Type':'application/json'},
      credentials:'same-origin',
      body:JSON.stringify(payload)
    })
    .then(function(r){ return r.json(); })
    .then(function(data){
      if(data && data.success){
        var barcodes = data.data && data.data.barcodes ? data.data.barcodes : [];
        var remaining = data.data ? data.data.remaining_pcs : 0;
        var remainingW = data.data ? data.data.remaining_weight_gram : 0;

        var fb = G('bcFormBody');
        if(fb){
          var html = '<div style="background:rgba(34,197,94,.1);border:1.5px solid rgba(34,197,94,.3);border-radius:12px;padding:18px;text-align:center;">';
          html += '<div style="color:#22C55E;font-size:22px;margin-bottom:8px;">✅</div>';
          html += '<div style="color:#22C55E;font-size:16px;font-weight:800;margin-bottom:4px;">' + bn(barcodes.length) + 'টি বারকোড তৈরি হয়েছে!</div>';
          html += '<div style="color:#8B95A7;font-size:13px;margin-bottom:14px;">বাকি: ' + bn(remaining) + ' পিস | ' + bn(num(remainingW).toFixed(3)) + 'g</div>';
          html += '<div style="background:#080F1E;border-radius:8px;padding:12px;text-align:left;">';
          html += '<div style="color:#8B95A7;font-size:11px;font-weight:700;margin-bottom:6px;">তৈরি হওয়া বারকোড:</div>';

          barcodes.forEach(function(bc){
            var w = num(bc.gross_weight_gram || bc.weight || bc.weight_gram);
            html += '<div style="font-family:monospace;color:#F5B800;font-size:14px;padding:3px 0;">' +
              esc(bc.barcode || bc.barcode_no || '') +
              ' <span style="color:#8B95A7;font-size:12px;">' +
              esc(bc.item_name || bc.product_name || '') +
              ' | ' + esc(bc.karat || '') +
              ' | ' + bn(w.toFixed(3)) + 'g</span></div>';
          });

          html += '</div></div>';
          fb.innerHTML = html;
        }

        if(btn){
          btn.disabled = false;
          btn.textContent = '✅ সম্পন্ন';
        }

        setTimeout(function(){
          closeBarcodeModal();
          loadList();
        }, 2500);
      } else {
        showBox(er, '❌ ' + apiMessage(data, 'ব্যর্থ'));
        if(btn){
          btn.disabled = false;
          btn.textContent = '✅ বারকোড সেভ করুন';
        }
      }
    })
    .catch(function(e){
      showBox(er, '❌ সার্ভার এরর: ' + (e.message || ''));
      if(btn){
        btn.disabled = false;
        btn.textContent = '✅ বারকোড সেভ করুন';
      }
    });
  }

  window.lpur = loadList;
  window.deleteStock = deleteStock;

  document.addEventListener('click', function(e){
    var t = e.target;
    if(!t) return;

    if(t.closest){
      var item = t.closest('.p-item');
      if(item && item.dataset && item.dataset.partyId){
        selectParty(item.dataset.partyCtx || 'm', item.dataset.partyId);
        return;
      }

      var addParty = t.closest('.p-add');
      if(addParty && addParty.dataset && addParty.dataset.paCtx){
        activePartyContext = addParty.dataset.paCtx;
        openQuickParty();
        return;
      }
    }

    if(t.id === 'mPartySelClear'){ clearParty('m'); return; }
    if(t.id === 'ePartySelClear'){ clearParty('e'); return; }

    if(t.id === 'qpCancel'){ closeQuickParty(); return; }
    if(t.id === 'qpSave'){ saveQuickParty(); return; }
    if(t.id === 'quickPartyModal'){ closeQuickParty(); return; }

    if(t.id === 'addBtn'){ openSingleModal(); return; }
    if(t.id === 'cancelBtn'){ closeSingleModal(); return; }
    if(t.id === 'mBtn'){ saveSingle(); return; }
    if(t.id === 'searchBtn'){ loadList(); return; }
    if(t.id === 'purModal'){ closeSingleModal(); return; }

    if(t.dataset && t.dataset.editId){ openEditModal(t.dataset.editId); return; }
    if(t.id === 'eCancelBtn'){ closeEditModal(); return; }
    if(t.id === 'eSaveBtn'){ saveEdit(); return; }
    if(t.id === 'editModal'){ closeEditModal(); return; }

    if(t.closest){
      var tog = t.closest('#eUpdatePayToggle');
      if(tog && t.id !== 'ePayment' && t.id !== 'eCashAcc'){
        togglePaySection();
        return;
      }
    }

    if(t.dataset && t.dataset.delId){
      deleteStock(t.dataset.delId, t.dataset.delName || '', t.dataset.delAmt || '৳০');
      return;
    }

    if(t.dataset && t.dataset.barcodeId){ openBarcodeModal(t.dataset.barcodeId); return; }
    if(t.id === 'bcCancelBtn' || t.id === 'bcCancelBtn2'){ closeBarcodeModal(); return; }
    if(t.id === 'bcSaveBtn'){ saveBarcodeTransfer(); return; }

    var wrap = t.closest ? t.closest('.party-wrap') : null;
    if(!wrap) hideAllPartyDrops();
  });

  document.addEventListener('input', function(e){
    var id = e.target ? e.target.id : '';

    if(['wVori','wAna','wRoti','wPoint'].indexOf(id) >= 0) mDoWeight();
    else if(['mRate','mPieces'].indexOf(id) >= 0) mDoCalc();
    else if(id === 'mPartySearch') showPartyDrop('m');

    else if(['eVori','eAna','eRoti','ePoint','eRate','ePieces'].indexOf(id) >= 0) eDoCalc();
    else if(id === 'ePartySearch') showPartyDrop('e');
  });

  document.addEventListener('focusin', function(e){
    if(e.target && e.target.id === 'mPartySearch') showPartyDrop('m');
    else if(e.target && e.target.id === 'ePartySearch') showPartyDrop('e');
  });

  document.addEventListener('change', function(e){
    if(e.target && e.target.id === 'mKarat') mDoCalc();
    if(e.target && e.target.id === 'eKarat') eDoCalc();
  });

  function init(){
    injectBarcodeModal();

    if(G('fromDate') && !G('fromDate').value) G('fromDate').value = '2021-01-01';
    if(G('toDate') && !G('toDate').value) G('toDate').value = todayStr();

    loadParties();
    loadAccounts();
    loadList();
  }

  if(document.readyState === 'loading'){
    document.addEventListener('DOMContentLoaded', init);
  } else {
    init();
  }

})();