// ============================================================
// EAN-13 barcode encoder + 102x152mm thermal label renderer
// ============================================================
(function () {
  const L = ['0001101','0011001','0010011','0111101','0100011','0110001','0101111','0111011','0110111','0001011'];
  const G = ['0100111','0110011','0011011','0100001','0011101','0111001','0000101','0010001','0001001','0010111'];
  const R = ['1110010','1100110','1101100','1000010','1011100','1001110','1010000','1000100','1001000','1110100'];
  const PARITY = ['LLLLLL','LLGLGG','LLGGLG','LLGGGL','LGLLGG','LGGLLG','LGGGLL','LGLGLG','LGLGGL','LGGLGL'];

  // Returns the 95-module string for a 13-digit code (assumes valid check digit).
  function encodeEAN13(raw) {
    let code = String(raw).replace(/\D/g, '');
    if (code.length === 12) code += checkDigit(code);
    if (code.length !== 13) {
      // pad / trim defensively so preview never crashes
      code = (code + '0000000000000').slice(0, 13);
    }
    const first = +code[0];
    const parity = PARITY[first];
    let bits = '101'; // start guard
    for (let i = 0; i < 6; i++) {
      const d = +code[1 + i];
      bits += parity[i] === 'L' ? L[d] : G[d];
    }
    bits += '01010'; // center guard
    for (let i = 0; i < 6; i++) bits += R[+code[7 + i]];
    bits += '101'; // end guard
    return { bits, code };
  }

  function checkDigit(code12) {
    let sum = 0;
    for (let i = 0; i < 12; i++) sum += (+code12[i]) * (i % 2 === 0 ? 1 : 3);
    return (10 - (sum % 10)) % 10;
  }

  // Render crisp SVG bars. moduleW in px. Guard bars extend below baseline.
  function BarcodeSVG({ code, height = 56, moduleW = 1.7, color = '#0a0a0a', showText = true, fontSize = 8.5 }) {
    const { bits, code: full } = encodeEAN13(code);
    const guardIdx = new Set();
    // start guard modules 0-2, center 45-49, end 92-94
    [0,1,2, 45,46,47,48,49, 92,93,94].forEach(i => guardIdx.add(i));
    const totalW = bits.length * moduleW;
    const textH = showText ? fontSize + 3 : 0;
    const barH = height - textH;
    const guardExtra = showText ? textH * 0.55 : 0;
    const rects = [];
    let x = 0;
    for (let i = 0; i < bits.length; i++) {
      if (bits[i] === '1') {
        const h = guardIdx.has(i) ? barH + guardExtra : barH;
        rects.push(React.createElement('rect', { key: i, x: x, y: 0, width: moduleW + 0.02, height: h, fill: color, shapeRendering: 'crispEdges' }));
      }
      x += moduleW;
    }
    const left = full.slice(1, 7), right = full.slice(7, 13);
    const children = [React.createElement('g', { key: 'bars' }, rects)];
    if (showText) {
      const ty = height - 1.5;
      const mk = (t, tx, anchor) => React.createElement('text', { key: 'txt' + tx, x: tx, y: ty, fontSize: fontSize, fontFamily: "'IBM Plex Mono', monospace", fontWeight: 600, fill: color, textAnchor: anchor, letterSpacing: 0.3 }, t);
      children.push(mk(full[0], -1.5, 'end'));
      children.push(mk(left, 3 * moduleW + (42 * moduleW) / 2, 'middle'));
      children.push(mk(right, 50 * moduleW + (42 * moduleW) / 2, 'middle'));
    }
    return React.createElement('svg', {
      width: totalW + (showText ? 12 : 0), height: height,
      viewBox: `${showText ? -11 : 0} 0 ${totalW + (showText ? 12 : 0)} ${height}`,
      style: { display: 'block', shapeRendering: 'crispEdges' }
    }, children);
  }

  // ---- 38mm x 25mm thermal label (landscape). Rendered white sticker. ----
  // scale = px per mm for preview. Real print = 203dpi (8 dots/mm).
  function ThermalLabel({ product, mfg, exp, batch, labelW = 102, labelH = 152, scale = 5 }) {
    if (!product) return null;
    const W = labelW * scale, H = labelH * scale;
    const pad = Math.max(1.6, labelW * 0.04) * scale / 4;
    const brandColor = '#0a0a0a';
    const title = (product.title || '').replace(product.brand, '').trim() || product.title;
    const S = (mm) => mm * scale;
    return React.createElement('div', {
      className: 'thermal-label',
      style: {
        width: W, height: H, background: '#fff', color: '#0a0a0a',
        position: 'relative', boxSizing: 'border-box', padding: pad,
        display: 'flex', flexDirection: 'column', overflow: 'hidden',
        fontFamily: "'IBM Plex Sans', sans-serif", lineHeight: 1.05,
        borderRadius: Math.max(2, scale * 0.5)
      }
    },
      // header: brand + mrp
      React.createElement('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', borderBottom: '1.2px solid #0a0a0a', paddingBottom: S(0.4) } },
        React.createElement('span', { style: { fontFamily: "'Space Grotesk', sans-serif", fontWeight: 700, fontSize: S(2.3), letterSpacing: S(0.05), lineHeight: 1 } }, product.brand),
        React.createElement('span', { style: { fontFamily: "'Space Grotesk', sans-serif", fontWeight: 700, fontSize: S(2.4), lineHeight: 1 } }, product.mrp)
      ),
      // title
      React.createElement('div', { style: { fontSize: S(1.78), fontWeight: 600, marginTop: S(0.5), display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden', minHeight: S(4) } }, title),
      // netwt + batch
      React.createElement('div', { style: { display: 'flex', justifyContent: 'space-between', fontSize: S(1.5), fontWeight: 500, marginTop: S(0.3), color: '#1a1a1a' } },
        React.createElement('span', null, 'Net Wt: ', React.createElement('b', null, product.netwt || '—')),
        React.createElement('span', null, 'B.No: ', React.createElement('b', null, batch || product.batch || '—'))
      ),
      // barcode
      React.createElement('div', { style: { flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', marginTop: S(0.3) } },
        React.createElement(BarcodeSVG, { code: product.barcode, height: S(8.2), moduleW: (W - pad * 2 - S(3)) / 95, fontSize: S(1.9) })
      ),
      // footer: mfg / exp / sku
      React.createElement('div', { style: { display: 'flex', justifyContent: 'space-between', fontSize: S(1.45), fontWeight: 600, marginTop: S(0.2), borderTop: '0.8px solid #0a0a0a', paddingTop: S(0.35) } },
        React.createElement('span', null, 'MFG ', mfg || product.mfg),
        React.createElement('span', null, 'EXP ', exp || product.exp)
      ),
      React.createElement('div', { style: { fontSize: S(1.3), fontWeight: 500, color: '#333', fontFamily: "'IBM Plex Mono', monospace", marginTop: S(0.1), textAlign: 'center', letterSpacing: S(0.02) } }, product.sku)
    );
  }

  // ---- TSPL (TSC printer language) command generator over TCP ----
  function buildTSPL({ product, mfg, exp, batch, qty, density = 12, speed = 4, labelW = 102, labelH = 152, gap = 2 }) {
    const title = (product.title || '').replace(/"/g, "'");
    const margin = Math.max(6, Math.round(labelW * 0.06));
    const infoY = margin + 26;
    const barcodeY = infoY + 22;
    const footerY = Math.max(barcodeY + Math.round(labelH * 0.28) + 18, labelH - 24);
    const barcodeNarrow = Math.max(3, Math.min(6, Math.round(labelW / 20)));
    const barcodeWide = Math.max(2, Math.min(6, barcodeNarrow * 2));
    const lines = [];
    lines.push(`SIZE ${labelW} mm, ${labelH} mm`);
    lines.push(`GAP ${gap} mm, 0 mm`);
    lines.push('DIRECTION 1');
    lines.push('REFERENCE 0,0');
    lines.push('CLS');
    lines.push(`DENSITY ${density}`);
    lines.push(`SPEED ${speed}`);
    lines.push(`TEXT ${margin},${margin + 8},"3",0,1,1,"${product.brand}"`);
    lines.push(`TEXT ${Math.max(margin, labelW - margin - 120)},${margin + 8},"3",0,1,1,"${product.mrp}"`);
    lines.push(`TEXT ${margin},${margin + 28},"2",0,1,1,"${title.slice(0, 48)}"`);
    lines.push(`TEXT ${margin},${infoY},"1",0,1,1,"Net Wt: ${product.netwt}   B.No: ${batch || product.batch}"`);
    lines.push(`BARCODE ${margin + 10},${barcodeY},"EAN13",${Math.max(45, Math.round(labelH * 0.28))},1,0,${barcodeNarrow},${barcodeWide},"${product.barcode.slice(0, 12)}"`);
    lines.push(`TEXT ${margin},${footerY},"1",0,1,1,"MFG ${mfg || product.mfg}   EXP ${exp || product.exp}   ${product.sku}"`);
    lines.push(`PRINT 1,${qty}`);
    return lines.join('\n');
  }

  Object.assign(window, { encodeEAN13, checkDigit, BarcodeSVG, ThermalLabel, buildTSPL });
})();
