/* global React, I, UI, SSSData */
const { useState: useStateI, useMemo: useMemoI, useRef: useRefI, useEffect: useEffectI } = React;

// ---------- รูปสินค้า: อัพโหลด / ถ่ายรูป ----------
function resizeProductImage(file, max = 640) {
  if (window.DeliveryStore && window.DeliveryStore.resizeImage) return window.DeliveryStore.resizeImage(file, max);
  return new Promise(resolve => {
    const r = new FileReader();
    r.onload = () => {
      const img = new Image();
      img.onload = () => {
        const scale = Math.min(1, max / Math.max(img.width, img.height));
        const c = document.createElement("canvas");
        c.width = Math.max(1, Math.round(img.width * scale));
        c.height = Math.max(1, Math.round(img.height * scale));
        c.getContext("2d").drawImage(img, 0, 0, c.width, c.height);
        resolve(c.toDataURL("image/jpeg", 0.72));
      };
      img.onerror = () => resolve(null);
      img.src = r.result;
    };
    r.readAsDataURL(file);
  });
}

function CameraCaptureModal({ onClose, onCapture, title = "ถ่ายรูปสินค้า" }) {
  const { Btn } = window.UI;
  const videoRef = useRefI(null);
  const streamRef = useRefI(null);
  const [shot, setShot] = useStateI(null);   // dataURL after snap
  const [err, setErr] = useStateI(null);

  useEffectI(() => {
    let cancelled = false;
    (async () => {
      try {
        const stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: "environment" }, audio: false });
        if (cancelled) { stream.getTracks().forEach(t => t.stop()); return; }
        streamRef.current = stream;
        if (videoRef.current) videoRef.current.srcObject = stream;
      } catch (e) {
        if (!cancelled) setErr("เปิดกล้องไม่ได้ — กรุณาอนุญาตการใช้กล้อง หรือแนบรูปจากเครื่องแทน");
      }
    })();
    return () => {
      cancelled = true;
      if (streamRef.current) streamRef.current.getTracks().forEach(t => t.stop());
    };
  }, []);

  const snap = () => {
    const v = videoRef.current;
    if (!v || !v.videoWidth) return;
    const max = 800;
    const scale = Math.min(1, max / Math.max(v.videoWidth, v.videoHeight));
    const c = document.createElement("canvas");
    c.width = Math.round(v.videoWidth * scale);
    c.height = Math.round(v.videoHeight * scale);
    c.getContext("2d").drawImage(v, 0, 0, c.width, c.height);
    setShot(c.toDataURL("image/jpeg", 0.78));
  };

  const fallbackPick = async (e) => {
    const f = e.target.files && e.target.files[0];
    e.target.value = "";
    if (!f) return;
    const url = await resizeProductImage(f, 640);
    if (url) { onCapture(url); onClose(); }
  };

  return (
    <>
      <div className="scrim" style={{zIndex: 80}} onClick={onClose}></div>
      <div style={{position: "fixed", left: "50%", top: "50%", transform: "translate(-50%, -50%)", zIndex: 81, background: "var(--surface)", border: "1px solid var(--line)", borderRadius: 12, padding: 16, width: "min(520px, calc(100vw - 32px))", boxShadow: "var(--shadow-lg)"}}>
        <div style={{display: "flex", alignItems: "center", gap: 8, marginBottom: 12}}>
          <I.camera size={16}/>
          <div style={{fontSize: 14, fontWeight: 600, flex: 1}}>{title}</div>
          <button className="icon-btn" onClick={onClose}><I.close size={14}/></button>
        </div>

        {err ? (
          <div style={{padding: 20, textAlign: "center", border: "1.5px dashed var(--line-strong)", borderRadius: 10, background: "var(--surface-2)"}}>
            <div style={{fontSize: 13, color: "var(--ink-2)", marginBottom: 12}}>{err}</div>
            <label className="btn primary" style={{cursor: "pointer"}}>
              <input type="file" accept="image/*" capture="environment" style={{display: "none"}} onChange={fallbackPick}></input>
              ถ่าย/เลือกรูปจากอุปกรณ์
            </label>
          </div>
        ) : shot ? (
          <>
            <img src={shot} alt="preview" style={{width: "100%", borderRadius: 10, border: "1px solid var(--line)", display: "block"}}/>
            <div style={{display: "flex", gap: 8, justifyContent: "flex-end", marginTop: 12}}>
              <Btn kind="ghost" onClick={() => setShot(null)}>ถ่ายใหม่</Btn>
              <Btn kind="primary" icon={I.check} onClick={() => { onCapture(shot); onClose(); }}>ใช้รูปนี้</Btn>
            </div>
          </>
        ) : (
          <>
            <video ref={videoRef} autoPlay playsInline muted style={{width: "100%", aspectRatio: "4 / 3", objectFit: "cover", borderRadius: 10, background: "#000", display: "block"}}></video>
            <div style={{display: "flex", gap: 8, justifyContent: "flex-end", marginTop: 12}}>
              <Btn kind="ghost" onClick={onClose}>ยกเลิก</Btn>
              <Btn kind="primary" icon={I.camera} onClick={snap}>ถ่ายภาพ</Btn>
            </div>
          </>
        )}
      </div>
    </>
  );
}

function ProductPhotoInput({ value, onChange, size = 110 }) {
  const { Btn } = window.UI;
  const [showCam, setShowCam] = useStateI(false);
  const pick = async (e) => {
    const f = e.target.files && e.target.files[0];
    e.target.value = "";
    if (!f) return;
    const url = await resizeProductImage(f, 640);
    if (url) onChange(url);
  };
  return (
    <div className="field">
      <label>รูปสินค้า</label>
      <div style={{display: "flex", gap: 12, alignItems: "flex-start"}}>
        {value ? (
          <div style={{position: "relative", width: size, height: size, flexShrink: 0}}>
            <img src={value} alt="รูปสินค้า" style={{width: size, height: size, objectFit: "cover", borderRadius: 10, border: "1px solid var(--line)", display: "block"}}/>
            <button title="ลบรูป" onClick={() => onChange(null)} style={{position: "absolute", top: 4, right: 4, width: 20, height: 20, borderRadius: "50%", background: "rgba(0,0,0,0.72)", color: "white", border: 0, cursor: "pointer", fontSize: 12, lineHeight: "18px", padding: 0}}>×</button>
          </div>
        ) : (
          <div style={{width: size, height: size, flexShrink: 0, border: "1.5px dashed var(--line-strong)", borderRadius: 10, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 6, color: "var(--ink-3)", background: "var(--surface-2)"}}>
            <I.camera size={22}/>
            <span style={{fontSize: 10.5}}>ยังไม่มีรูป</span>
          </div>
        )}
        <div style={{display: "flex", flexDirection: "column", gap: 6}}>
          <label className="btn sm" style={{cursor: "pointer", justifyContent: "center"}}>
            <input type="file" accept="image/*" style={{display: "none"}} onChange={pick}></input>
            อัพโหลดรูป
          </label>
          <Btn size="sm" icon={I.camera} onClick={() => setShowCam(true)}>ถ่ายรูป</Btn>
          <div style={{fontSize: 10.5, color: "var(--ink-3)", maxWidth: 150}}>รองรับ JPG/PNG · ระบบย่อรูปให้อัตโนมัติ</div>
        </div>
      </div>
      {showCam && <CameraCaptureModal onClose={() => setShowCam(false)} onCapture={onChange}/>}
    </div>
  );
}

// Persist user-side product changes in localStorage
function loadOverrides() { try { return JSON.parse(localStorage.getItem("sss-products") || "null"); } catch { return null; } }
function saveOverrides(list) { try { localStorage.setItem("sss-products", JSON.stringify(list)); } catch {} }

function InventoryProducts({ navigate }) {
  const D = window.SSSData;
  const { Btn, Badge, Card, PageHead, Drawer, BarcodeVisual, fmt0 } = window.UI;
  const [products, setProducts] = useStateI(() => loadOverrides() || D.Products);
  const [active, setActive] = useStateI(null);
  const [editMode, setEditMode] = useStateI(false);
  const [showNew, setShowNew] = useStateI(false);
  const [showStock, setShowStock] = useStateI(null); // product to adjust
  const [q, setQ] = useStateI("");
  const [cat, setCat] = useStateI("ทั้งหมด");

  // Keep D.Products in sync
  React.useEffect(() => {
    D.Products.length = 0;
    D.Products.push(...products);
    saveOverrides(products);
  }, [products]);

  const cats = ["ทั้งหมด", "แผ่นสแตนเลส", "ท่อสแตนเลส", "แผ่นเหล็ก", "เหล็กกล่อง", "งานสำเร็จ", "บริการ"];
  const filtered = products.filter(p => (cat === "ทั้งหมด" || p.category === cat) && (!q || (p.name + p.sku + p.barcode).toLowerCase().includes(q.toLowerCase())));

  const addProduct = (p) => {
    setProducts(list => [...list, p]);
    setShowNew(false);
    window.toast && window.toast("เพิ่มสินค้า " + p.sku + " แล้ว");
  };
  const updateProduct = (sku, patch) => {
    setProducts(list => list.map(p => p.sku === sku ? { ...p, ...patch } : p));
    if (active && active.sku === sku) setActive({ ...active, ...patch });
  };
  const deleteProduct = async (sku) => {
    const p = products.find(x => x.sku === sku);
    const ok = await window.confirmDelete("สินค้า " + sku, p?.name);
    if (!ok) return;
    setProducts(list => list.filter(p => p.sku !== sku));
    setActive(null);
    window.toast && window.toast("ลบสินค้าแล้ว");
  };
  const adjustStock = (sku, delta, reason) => {
    setProducts(list => list.map(p => p.sku === sku ? { ...p, stock: Math.max(0, p.stock + delta) } : p));
    // Add to movements
    const product = products.find(p => p.sku === sku);
    if (product) {
      D.InventoryMoves.unshift({
        date: new Date().toLocaleString("th-TH", { day: "2-digit", month: "2-digit", year: "2-digit", hour: "2-digit", minute: "2-digit" }),
        type: delta > 0 ? "รับเข้า" : "เบิกใช้งาน",
        sku, name: product.name, qty: delta,
        ref: reason || "ADJ-MANUAL",
        by: "ปิยะ ศ."
      });
    }
    if (active && active.sku === sku) setActive({ ...active, stock: Math.max(0, active.stock + delta) });
    window.toast && window.toast((delta > 0 ? "+" : "") + delta + " " + sku);
  };

  return (
    <>
      <PageHead
        title="สินค้าและสต็อก"
        sub={`จัดการสินค้า · พิมพ์บาร์โค้ด · ติดตามคงคลังแบบเรียลไทม์ (${products.length} SKU)`}
        right={<>
          <Btn icon={I.qr} kind="ghost" onClick={() => navigate("barcode")}>สแกน/พิมพ์บาร์โค้ด</Btn>
          <Btn icon={I.download} kind="ghost" onClick={() => window.exportRowsCSV("products", [
            { key: "sku", label: "SKU" }, { key: "name", label: "สินค้า" }, { key: "category", label: "หมวด" },
            { key: "location", label: "Location" }, { key: "cost", label: "ต้นทุน" }, { key: "price", label: "ราคาขาย" },
            { key: "stock", label: "คงเหลือ" }, { key: "unit", label: "หน่วย" }
          ], filtered)}>นำเข้า/ส่งออก</Btn>
          <Btn icon={I.plus} kind="primary" onClick={() => setShowNew(true)}>เพิ่มสินค้า</Btn>
        </>}
      />

      <div className="grid cols-4 mb-lg">
        <window.UI.Stat label="สินค้าทั้งหมด" value={products.length} sub={`${cats.length - 2} หมวด · ${products.filter(p => p.category === "บริการ").length} เป็นบริการ`} icon={I.box}/>
        <window.UI.Stat label="มูลค่าสต็อกรวม" value={`฿${fmt0(products.filter(p=>p.category!=='บริการ').reduce((s,p)=>s+p.stock*p.cost,0))}`} sub="ตามต้นทุน" icon={I.warehouse}/>
        <window.UI.Stat label="สต็อกใกล้หมด" value={products.filter(p=>p.stock<=p.min&&p.category!=='บริการ').length} sub="ต้องสั่งซื้อเพิ่ม" dir="down" icon={I.bell}/>
        <window.UI.Stat label="การเคลื่อนไหววันนี้" value={D.InventoryMoves.filter(m=>m.date.startsWith("22")).length} sub="ดูประวัติเต็มที่หน้าการเคลื่อนไหว" icon={I.move}/>
      </div>

      <Card flush>
        <div style={{padding: 12, display: "flex", gap: 10, alignItems: "center", flexWrap: "wrap", borderBottom: "1px solid var(--line)"}}>
          <div style={{display: "flex", gap: 4, flexWrap: "wrap"}}>
            {cats.map(c => (
              <button key={c} className={`btn sm ${cat === c ? "primary" : "ghost"}`} onClick={() => setCat(c)}>{c}</button>
            ))}
          </div>
          <span className="spacer"/>
          <div className="search" style={{width: 280}}>
            <I.search size={14}/>
            <input placeholder="ค้นหาชื่อ / SKU / บาร์โค้ด…" value={q} onChange={e=>setQ(e.target.value)}/>
          </div>
        </div>

        <div className="table-wrap">
          <table className="t">
            <thead>
              <tr>
                <th>SKU</th>
                <th>สินค้า</th>
                <th>หมวด</th>
                <th>Location</th>
                <th className="right">ต้นทุน</th>
                <th className="right">ราคาขาย</th>
                <th className="right">คงเหลือ</th>
                <th>สถานะ</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {filtered.map(p => {
                const low = p.stock <= p.min && p.category !== "บริการ";
                const out = p.stock <= 0 && p.category !== "บริการ";
                return (
                  <tr key={p.sku} className="row-clickable" onClick={() => setActive(p)}>
                    <td className="mono">{p.sku}</td>
                    <td style={{maxWidth: 340}}>
                      <div style={{display: "flex", alignItems: "center", gap: 10, minWidth: 0}}>
                        {p.photo
                          ? <img src={p.photo} alt="" style={{width: 32, height: 32, objectFit: "cover", borderRadius: 6, border: "1px solid var(--line)", flexShrink: 0, display: "block"}}/>
                          : <div style={{width: 32, height: 32, borderRadius: 6, border: "1px dashed var(--line-strong)", background: "var(--surface-2)", display: "grid", placeItems: "center", color: "var(--ink-3)", flexShrink: 0}}><I.camera size={13}/></div>}
                        <span style={{overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap"}}>{p.name}</span>
                      </div>
                    </td>
                    <td className="muted">{p.category}</td>
                    <td className="mono" style={{fontSize: 12}}>{p.location}</td>
                    <td className="right amount muted">{p.cost > 0 ? `฿${fmt0(p.cost)}` : "—"}</td>
                    <td className="right amount">฿{fmt0(p.price)}</td>
                    <td className="right amount" style={{color: out ? "var(--danger)" : low ? "var(--warning)" : "var(--ink-1)"}}>
                      {p.category === "บริการ" ? "∞" : `${p.stock} ${p.unit}`}
                    </td>
                    <td>
                      {p.category === "บริการ" ? <Badge tone="outline">บริการ</Badge>
                        : out ? <Badge tone="danger">หมด</Badge>
                        : low ? <Badge tone="warning">ใกล้หมด</Badge>
                        : <Badge tone="success">พร้อมขาย</Badge>}
                    </td>
                    <td onClick={e => e.stopPropagation()}>
                      <div style={{display: "flex", gap: 2}}>
                        {p.category !== "บริการ" && (
                          <>
                            <button className="icon-btn" title="รับเข้า" onClick={() => setShowStock({ product: p, mode: "in" })}><I.plus size={12}/></button>
                            <button className="icon-btn" title="เบิกออก" onClick={() => setShowStock({ product: p, mode: "out" })}><I.arrowDown size={12}/></button>
                          </>
                        )}
                        <button className="icon-btn" title="แก้ไข" onClick={() => { setActive(p); setEditMode(true); }}><I.edit size={12}/></button>
                      </div>
                    </td>
                  </tr>
                );
              })}
              {filtered.length === 0 && (
                <tr><td colSpan={9} style={{padding: 24, textAlign: "center", color: "var(--ink-3)"}}>ไม่พบสินค้า · <button className="btn sm" onClick={() => setShowNew(true)}>เพิ่มสินค้าใหม่</button></td></tr>
              )}
            </tbody>
          </table>
        </div>
      </Card>

      {/* Product detail drawer with edit */}
      <Drawer open={!!active} onClose={() => { setActive(null); setEditMode(false); }} title={active ? (editMode ? "แก้ไขสินค้า " + active.sku : "สินค้า " + active.sku) : ""} wide
        footer={editMode ? (
          <>
            <Btn kind="ghost" onClick={() => setEditMode(false)}>ยกเลิก</Btn>
            <Btn kind="danger" icon={I.trash} onClick={() => deleteProduct(active.sku)}>ลบสินค้า</Btn>
            <Btn kind="primary" icon={I.check} onClick={() => { setEditMode(false); window.toast && window.toast("บันทึกแล้ว"); }}>บันทึก</Btn>
          </>
        ) : (
          <>
            <Btn kind="ghost" icon={I.print} onClick={() => navigate("barcode")}>พิมพ์บาร์โค้ด</Btn>
            <Btn kind="primary" icon={I.edit} onClick={() => setEditMode(true)}>แก้ไข</Btn>
          </>
        )}>
        {active && (editMode ? <ProductEdit p={active} update={updateProduct}/> : <ProductView p={active} adjust={adjustStock}/>)}
      </Drawer>

      {/* New product modal */}
      {showNew && <NewProductModal onClose={() => setShowNew(false)} onSave={addProduct}/>}

      {/* Stock adjust modal */}
      {showStock && <StockAdjustModal target={showStock} onClose={() => setShowStock(null)} onApply={(delta, reason) => { adjustStock(showStock.product.sku, delta, reason); setShowStock(null); }}/>}
    </>
  );
}

function ProductView({ p, adjust }) {
  const D = window.SSSData;
  const { fmt0, BarcodeVisual } = window.UI;
  return (
    <div style={{display: "flex", flexDirection: "column", gap: 16}}>
      <div style={{display: "grid", gridTemplateColumns: "1fr 200px", gap: 16, alignItems: "flex-start"}}>
        <div>
          {p.photo && (
            <img src={p.photo} alt={p.name} style={{width: "100%", maxWidth: 360, maxHeight: 220, objectFit: "cover", borderRadius: 10, border: "1px solid var(--line)", display: "block", marginBottom: 12}}/>
          )}
          <div className="label">ชื่อสินค้า</div>
          <div style={{fontSize: 16, fontWeight: 600, marginBottom: 12}}>{p.name}</div>
          <div className="field-row cols-2">
            <div><div className="label">SKU</div><div className="mono">{p.sku}</div></div>
            <div><div className="label">หมวด</div><div>{p.category}</div></div>
            <div><div className="label">หน่วยนับ</div><div>{p.unit}</div></div>
            <div><div className="label">ตำแหน่งจัดเก็บ</div><div className="mono">{p.location}</div></div>
            <div><div className="label">ต้นทุน</div><div className="amount">฿{fmt0(p.cost)}</div></div>
            <div><div className="label">ราคาขาย</div><div className="amount">฿{fmt0(p.price)}</div></div>
          </div>
        </div>
        <div style={{textAlign: "center", padding: "8px 0"}}>
          {p.barcode !== "—" && <BarcodeVisual code={p.barcode} width={180}/>}
          {p.barcode === "—" && <div style={{padding: 30, color: "var(--ink-3)", textAlign: "center", fontSize: 12, border: "1px dashed var(--line)", borderRadius: 8}}>บริการ — ไม่มีบาร์โค้ด</div>}
        </div>
      </div>

      <div className="grid cols-3" style={{gap: 10}}>
        <div className="stat"><div className="label">คงเหลือปัจจุบัน</div><div className="value">{p.stock} {p.unit}</div></div>
        <div className="stat"><div className="label">ขั้นต่ำ / สูงสุด</div><div className="value" style={{fontSize: 17}}>{p.min} / {p.max}</div></div>
        <div className="stat"><div className="label">มูลค่าสต็อก</div><div className="value">฿{fmt0(p.cost * p.stock)}</div></div>
      </div>

      {p.category !== "บริการ" && (
        <div className="card" style={{padding: 14}}>
          <div className="h2 mb">ปรับสต็อกด่วน</div>
          <div style={{display: "grid", gridTemplateColumns: "1fr 1fr 1fr 1fr", gap: 6}}>
            <button className="btn" onClick={() => adjust(p.sku, +1)}>+1</button>
            <button className="btn" onClick={() => adjust(p.sku, +10)}>+10</button>
            <button className="btn" onClick={() => adjust(p.sku, -1)}>−1</button>
            <button className="btn" onClick={() => adjust(p.sku, -10)}>−10</button>
          </div>
        </div>
      )}

      <div>
        <div className="h2 mb">การเคลื่อนไหวล่าสุด</div>
        <div className="card" style={{padding: 0}}>
          <table className="t">
            <thead><tr><th>วันที่</th><th>ประเภท</th><th className="right">จำนวน</th><th>อ้างอิง</th><th>โดย</th></tr></thead>
            <tbody>
              {D.InventoryMoves.filter(m => m.sku === p.sku).slice(0, 6).map((m, i) => (
                <tr key={i}>
                  <td style={{fontSize: 12}}>{m.date}</td>
                  <td><window.UI.Badge>{m.type}</window.UI.Badge></td>
                  <td className="right amount" style={{color: m.qty > 0 ? "var(--success)" : "var(--danger)"}}>{m.qty > 0 ? "+" : ""}{m.qty} {p.unit}</td>
                  <td className="mono" style={{fontSize: 12}}>{m.ref}</td>
                  <td className="muted" style={{fontSize: 12}}>{m.by}</td>
                </tr>
              ))}
              {D.InventoryMoves.filter(m => m.sku === p.sku).length === 0 && (
                <tr><td colSpan={5} style={{padding: 16, textAlign: "center", color: "var(--ink-3)"}}>ยังไม่มีการเคลื่อนไหว</td></tr>
              )}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
}

function ProductEdit({ p, update }) {
  const [f, setF] = useStateI(p);
  const upd = (k, v) => { const next = { ...f, [k]: v }; setF(next); update(p.sku, { [k]: v }); };
  return (
    <div style={{display: "flex", flexDirection: "column", gap: 12}}>
      <ProductPhotoInput value={f.photo} onChange={url => upd("photo", url)}/>
      <div className="field"><label>ชื่อสินค้า</label><input className="input" value={f.name} onChange={e=>upd("name", e.target.value)}/></div>
      <div className="field-row cols-2">
        <div className="field"><label>SKU</label><input className="input mono" value={f.sku} readOnly style={{background: "var(--surface-2)"}}/></div>
        <div className="field"><label>บาร์โค้ด</label><input className="input mono" value={f.barcode} onChange={e=>upd("barcode", e.target.value)}/></div>
      </div>
      <div className="field-row cols-2">
        <div className="field"><label>หมวด</label>
          <select className="input" value={f.category} onChange={e=>upd("category", e.target.value)}>
            {["แผ่นสแตนเลส", "ท่อสแตนเลส", "แผ่นเหล็ก", "เหล็กกล่อง", "งานสำเร็จ", "บริการ"].map(c => <option key={c}>{c}</option>)}
          </select>
        </div>
        <div className="field"><label>หน่วย</label><input className="input" value={f.unit} onChange={e=>upd("unit", e.target.value)}/></div>
      </div>
      <div className="field-row cols-2">
        <div className="field"><label>ต้นทุน (บาท)</label><input className="input" type="number" value={f.cost} onChange={e=>upd("cost", +e.target.value)}/></div>
        <div className="field"><label>ราคาขาย (บาท)</label><input className="input" type="number" value={f.price} onChange={e=>upd("price", +e.target.value)}/></div>
      </div>
      <div className="field-row cols-3">
        <div className="field"><label>คงเหลือ</label><input className="input" type="number" value={f.stock} onChange={e=>upd("stock", +e.target.value)}/></div>
        <div className="field"><label>ขั้นต่ำ</label><input className="input" type="number" value={f.min} onChange={e=>upd("min", +e.target.value)}/></div>
        <div className="field"><label>สูงสุด</label><input className="input" type="number" value={f.max} onChange={e=>upd("max", +e.target.value)}/></div>
      </div>
      <div className="field"><label>ตำแหน่งจัดเก็บ</label><input className="input mono" value={f.location} onChange={e=>upd("location", e.target.value)}/></div>
    </div>
  );
}

function NewProductModal({ onClose, onSave }) {
  const { Btn, Drawer, BarcodeVisual } = window.UI;
  const [f, setF] = useStateI({
    source: "internal", sku: "", barcode: "", name: "", category: "งานสำเร็จ", unit: "ชิ้น",
    cost: 0, price: 0, stock: 0, min: 5, max: 100, location: "", photo: null
  });
  const upd = (k, v) => setF(p => ({ ...p, [k]: v }));
  const internal = f.source === "internal";

  // ===== Auto code generators for internal (ผลิตเอง) products =====
  const eanCheck = (d12) => {
    let sum = 0;
    for (let i = 0; i < 12; i++) sum += (+d12[i]) * (i % 2 === 0 ? 1 : 3);
    return String((10 - (sum % 10)) % 10);
  };
  const genInternalCodes = () => {
    const nums = (window.SSSData.Products || [])
      .map(p => (String(p.sku).match(/^FG-(\d+)$/) || [])[1])
      .filter(Boolean).map(Number);
    const n = (nums.length ? Math.max(...nums) : 0) + 1;
    const sku = "FG-" + String(n).padStart(4, "0");
    const base12 = "8851000" + String(n).padStart(5, "0"); // 885=TH GS1, 1000=SSS prefix
    const barcode = base12 + eanCheck(base12);
    return { sku, barcode };
  };
  const regen = () => { const c = genInternalCodes(); setF(p => ({ ...p, ...c })); };
  React.useEffect(() => {
    if (internal) setF(p => ({ ...p, ...genInternalCodes() }));
    else setF(p => ({ ...p, sku: "", barcode: "" }));
  }, [f.source]);

  const save = () => {
    if (!f.name) { window.toast && window.toast("กรุณากรอกชื่อสินค้า"); return; }
    if (!internal && !f.sku) { window.toast && window.toast("กรุณากรอก SKU สำหรับสินค้าซื้อมาขาย"); return; }
    const { source, ...rest } = f;
    onSave({ ...rest, sku: String(f.sku).toUpperCase(), internal });
  };
  return (
    <Drawer open={true} onClose={onClose} title="เพิ่มสินค้าใหม่" wide
      footer={<><Btn kind="ghost" onClick={onClose}>ยกเลิก</Btn><Btn kind="primary" icon={I.check} onClick={save}>บันทึก</Btn></>}>
      <div style={{display: "flex", flexDirection: "column", gap: 12}}>
        <div className="field">
          <label>ประเภทสินค้า</label>
          <div className="payseg" style={{display: "flex", width: "100%"}}>
            <button type="button" className={"payseg-btn" + (internal ? " active" : "")} style={{flex: 1}} onClick={() => upd("source", "internal")}>ผลิตเอง / สินค้าภายใน</button>
            <button type="button" className={"payseg-btn" + (!internal ? " active" : "")} style={{flex: 1}} onClick={() => upd("source", "external")}>ซื้อมาขาย</button>
          </div>
        </div>
        <div className="field"><label>ชื่อสินค้า *</label><input className="input" value={f.name} onChange={e=>upd("name", e.target.value)} placeholder="เช่น ราวบันไดสแตนเลส 304"/></div>
        <ProductPhotoInput value={f.photo} onChange={url => upd("photo", url)}/>
        <div className="field-row cols-2">
          <div className="field">
            <label style={{display: "flex", alignItems: "center", gap: 6}}>รหัสสินค้า (SKU){internal && <span className="auto-tag">อัตโนมัติ</span>}</label>
            <input className="input mono" value={f.sku} readOnly={internal} onChange={e=>upd("sku", e.target.value)} placeholder={internal ? "" : "SS304-SH-1.5"} style={internal ? {background: "var(--surface-2)", cursor: "default"} : {}}/>
          </div>
          <div className="field">
            <label style={{display: "flex", alignItems: "center", gap: 6}}>บาร์โค้ด (EAN-13){internal && <span className="auto-tag">สร้างให้อัตโนมัติ</span>}</label>
            <input className="input mono" value={f.barcode} readOnly={internal} onChange={e=>upd("barcode", e.target.value)} placeholder={internal ? "" : "8851000000000"} style={internal ? {background: "var(--surface-2)", cursor: "default"} : {}}/>
          </div>
        </div>
        {internal && (
          <div style={{display: "flex", alignItems: "center", gap: 14, padding: "10px 14px", background: "var(--brand-bg)", border: "1px solid var(--brand-soft)", borderRadius: 10}}>
            {BarcodeVisual && <BarcodeVisual code={f.barcode} height={34} width={120}/>}
            <div style={{flex: 1, minWidth: 0}}>
              <div style={{fontSize: 12.5, fontWeight: 600, color: "var(--brand-strong)"}}>ระบบออกรหัสและบาร์โค้ดให้อัตโนมัติ</div>
              <div style={{fontSize: 11.5, color: "var(--ink-3)"}}>SKU <b className="mono" style={{color: "var(--ink-1)"}}>{f.sku}</b> · บาร์โค้ด <b className="mono" style={{color: "var(--ink-1)"}}>{f.barcode}</b></div>
            </div>
            <Btn size="sm" kind="ghost" icon={I.sparkle} onClick={regen}>สร้างใหม่</Btn>
          </div>
        )}
        <div className="field-row cols-2">
          <div className="field"><label>หมวด</label>
            <select className="input" value={f.category} onChange={e=>upd("category", e.target.value)}>
              {["แผ่นสแตนเลส", "ท่อสแตนเลส", "แผ่นเหล็ก", "เหล็กกล่อง", "งานสำเร็จ", "บริการ"].map(c => <option key={c}>{c}</option>)}
            </select>
          </div>
          <div className="field"><label>หน่วย</label>
            <select className="input" value={f.unit} onChange={e=>upd("unit", e.target.value)}>
              {["ชิ้น", "แผ่น", "เส้น", "ใบ", "ชุด", "ม้วน", "lot", "ชม."].map(u => <option key={u}>{u}</option>)}
            </select>
          </div>
        </div>
        <div className="field-row cols-2">
          <div className="field"><label>ต้นทุน (บาท)</label><input className="input" type="number" value={f.cost} onChange={e=>upd("cost", +e.target.value)}/></div>
          <div className="field"><label>ราคาขาย (บาท)</label><input className="input" type="number" value={f.price} onChange={e=>upd("price", +e.target.value)}/></div>
        </div>
        <div className="field-row cols-3">
          <div className="field"><label>สต็อกเริ่มต้น</label><input className="input" type="number" value={f.stock} onChange={e=>upd("stock", +e.target.value)}/></div>
          <div className="field"><label>ขั้นต่ำ</label><input className="input" type="number" value={f.min} onChange={e=>upd("min", +e.target.value)}/></div>
          <div className="field"><label>สูงสุด</label><input className="input" type="number" value={f.max} onChange={e=>upd("max", +e.target.value)}/></div>
        </div>
        <div className="field"><label>ตำแหน่งจัดเก็บ</label><input className="input mono" value={f.location} onChange={e=>upd("location", e.target.value)} placeholder="A-01-01"/></div>
      </div>
    </Drawer>
  );
}

function StockAdjustModal({ target, onClose, onApply }) {
  const { Btn } = window.UI;
  const { product, mode } = target;
  const [qty, setQty] = useStateI(1);
  const [reason, setReason] = useStateI(mode === "in" ? "PO-2569-XXXX" : "JOB-2569-XXX");
  return (
    <>
      <div className="scrim" onClick={onClose}/>
      <div style={{position: "fixed", left: "50%", top: "50%", transform: "translate(-50%, -50%)", zIndex: 60, background: "var(--surface)", border: "1px solid var(--line)", borderRadius: 10, padding: 18, width: 400, boxShadow: "var(--shadow-lg)"}}>
        <div style={{fontSize: 14, fontWeight: 600, marginBottom: 12}}>{mode === "in" ? "รับสินค้าเข้า" : "เบิกสินค้าออก"} · {product.sku}</div>
        <div style={{fontSize: 13, color: "var(--ink-3)", marginBottom: 14}}>{product.name}<br/>คงเหลือปัจจุบัน <b style={{color: "var(--ink-1)"}}>{product.stock} {product.unit}</b></div>
        <div className="field mb"><label>จำนวน ({product.unit})</label>
          <input className="input" type="number" min="1" value={qty} onChange={e=>setQty(Math.max(1, +e.target.value || 1))} autoFocus/>
        </div>
        <div className="field mb"><label>อ้างอิง / เหตุผล</label>
          <input className="input" value={reason} onChange={e=>setReason(e.target.value)}/>
        </div>
        <div style={{display: "flex", gap: 8, justifyContent: "flex-end"}}>
          <Btn kind="ghost" onClick={onClose}>ยกเลิก</Btn>
          <Btn kind="primary" onClick={() => onApply(mode === "in" ? qty : -qty, reason)}>
            {mode === "in" ? "รับเข้า " + qty + " " + product.unit : "เบิกออก " + qty + " " + product.unit}
          </Btn>
        </div>
      </div>
    </>
  );
}

// ============ Stock Movements ============
function StockMovements({ navigate }) {
  const D = window.SSSData;
  const { Btn, Badge, Card, PageHead, fmt0 } = window.UI;
  const [moves, setMoves] = useStateI(D.InventoryMoves);
  const [showNew, setShowNew] = useStateI(false);

  const addMove = (m) => {
    const entry = {
      date: new Date().toLocaleString("th-TH", { day: "2-digit", month: "2-digit", year: "2-digit", hour: "2-digit", minute: "2-digit" }),
      type: m.type,
      sku: m.sku,
      name: m.name,
      qty: m.type === "รับเข้า" ? Math.abs(m.qty) : -Math.abs(m.qty),
      ref: m.ref || "MV-MANUAL",
      by: "ปิยะ ศ."
    };
    D.InventoryMoves.unshift(entry);
    setMoves([...D.InventoryMoves]);
    // Reflect in product stock
    const prod = D.Products.find(p => p.sku === m.sku);
    if (prod) prod.stock = Math.max(0, prod.stock + entry.qty);
    setShowNew(false);
    window.logActivity && window.logActivity("บันทึกการเคลื่อนไหว", `${entry.type} ${entry.sku} (${entry.qty > 0 ? "+" : ""}${entry.qty})`, "create");
    window.toast && window.toast(`บันทึก ${entry.type} ${entry.sku} แล้ว`);
  };

  return (
    <>
      <PageHead title="การเคลื่อนไหวสินค้า · Stock Movements"
        sub="ทุกการรับเข้า เบิกใช้งาน ขาย และปรับสต็อก"
        right={<><Btn icon={I.download} kind="ghost" onClick={() => window.exportRowsCSV("stock-movements", [
          { key: "date", label: "วันที่/เวลา" }, { key: "type", label: "ประเภท" }, { key: "sku", label: "SKU" },
          { key: "name", label: "สินค้า" }, { key: "qty", label: "จำนวน" }, { key: "ref", label: "อ้างอิง" }, { key: "by", label: "ผู้บันทึก" }
        ], moves)}>ส่งออก</Btn><Btn icon={I.plus} kind="primary" onClick={() => setShowNew(true)}>บันทึกการเคลื่อนไหว</Btn></>}/>
      <Card flush>
        <div className="table-wrap">
          <table className="t">
            <thead><tr><th>วันที่/เวลา</th><th>ประเภท</th><th>SKU</th><th>สินค้า</th><th className="right">จำนวน</th><th>อ้างอิง</th><th>ผู้บันทึก</th></tr></thead>
            <tbody>
              {moves.map((m, i) => (
                <tr key={i}>
                  <td className="mono" style={{fontSize: 12}}>{m.date}</td>
                  <td><Badge>{m.type}</Badge></td>
                  <td className="mono">{m.sku}</td>
                  <td>{m.name}</td>
                  <td className="right amount" style={{color: m.qty > 0 ? "var(--success)" : "var(--danger)"}}>{m.qty > 0 ? "+" : ""}{m.qty}</td>
                  <td className="mono" style={{fontSize: 12}}>{m.ref}</td>
                  <td className="muted">{m.by}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </Card>
      {showNew && <MovementModal onClose={() => setShowNew(false)} onSave={addMove}/>}
    </>
  );
}

function MovementModal({ onClose, onSave }) {
  const D = window.SSSData;
  const { Btn, Drawer } = window.UI;
  const products = D.Products;
  const [f, setF] = useStateI({
    type: "รับเข้า", sku: products[0]?.sku || "", qty: 1, ref: ""
  });
  const upd = (k, v) => setF(p => ({ ...p, [k]: v }));
  const prod = products.find(p => p.sku === f.sku);
  const types = ["รับเข้า", "เบิกใช้งาน", "ขาย", "ปรับสต็อก", "คืนสินค้า"];
  const isIn = f.type === "รับเข้า" || f.type === "คืนสินค้า";
  const save = () => {
    if (!f.sku) { window.toast && window.toast("เลือกสินค้าก่อน"); return; }
    if (!f.qty || f.qty <= 0) { window.toast && window.toast("กรอกจำนวนให้ถูกต้อง"); return; }
    onSave({ ...f, name: prod?.name || f.sku });
  };
  return (
    <Drawer open={true} onClose={onClose} title="บันทึกการเคลื่อนไหวสต็อก" wide
      footer={<><Btn kind="ghost" onClick={onClose}>ยกเลิก</Btn><Btn kind="primary" icon={I.check} onClick={save}>บันทึก</Btn></>}>
      <div style={{display: "flex", flexDirection: "column", gap: 12}}>
        <div className="field"><label>ประเภทการเคลื่อนไหว</label>
          <select className="input" value={f.type} onChange={e=>upd("type", e.target.value)}>
            {types.map(t => <option key={t}>{t}</option>)}
          </select>
        </div>
        <div className="field"><label>สินค้า (SKU)</label>
          <select className="input" value={f.sku} onChange={e=>upd("sku", e.target.value)}>
            {products.map(p => <option key={p.sku} value={p.sku}>{p.sku} · {p.name}</option>)}
          </select>
        </div>
        {prod && <div style={{fontSize: 12.5, color: "var(--ink-3)"}}>คงเหลือปัจจุบัน: <b style={{color: "var(--ink-1)"}}>{prod.stock} {prod.unit}</b> → หลังบันทึก: <b style={{color: "var(--accent)"}}>{Math.max(0, prod.stock + (isIn ? Math.abs(f.qty) : -Math.abs(f.qty)))} {prod.unit}</b></div>}
        <div className="field-row cols-2">
          <div className="field"><label>จำนวน {isIn ? "(เพิ่ม)" : "(ลด)"}</label><input className="input" type="number" min="1" value={f.qty} onChange={e=>upd("qty", +e.target.value)}/></div>
          <div className="field"><label>เลขที่อ้างอิง</label><input className="input mono" value={f.ref} onChange={e=>upd("ref", e.target.value)} placeholder={isIn ? "PO-2569-XXXX" : "JOB-2569-XXX"}/></div>
        </div>
      </div>
    </Drawer>
  );
}

// ---------- สแกนบาร์โค้ดด้วยกล้อง (ZXing — รองรับ iOS/Android) ----------
function BarcodeScanModal({ onClose, onDetected }) {
  const { Btn } = window.UI;
  const videoRef = useRefI(null);
  const readerRef = useRefI(null);
  const [err, setErr] = useStateI(null);
  const [ready, setReady] = useStateI(false);
  const [manual, setManual] = useStateI("");

  useEffectI(() => {
    let stopped = false;
    const Z = window.ZXing;
    if (!Z || !Z.BrowserMultiFormatReader) { setErr("ไม่พบไลบรารีสแกน — กรุณาพิมพ์รหัสเอง"); return; }
    const reader = new Z.BrowserMultiFormatReader();
    readerRef.current = reader;
    const cb = (result) => {
      if (stopped || !result) return;
      const text = result.getText ? result.getText() : result.text;
      if (text) { stopped = true; try { reader.reset(); } catch (e) {} onDetected(String(text)); }
    };
    const onErr = () => { if (!stopped) setErr("เปิดกล้องไม่ได้ — กรุณาอนุญาตให้ใช้กล้อง หรือพิมพ์รหัสเอง"); };
    const constraints = { video: { facingMode: { ideal: "environment" } }, audio: false };
    try {
      const started = typeof reader.decodeFromConstraints === "function" ?
        reader.decodeFromConstraints(constraints, videoRef.current, cb) :
        reader.decodeFromVideoDevice(null, videoRef.current, cb);
      Promise.resolve(started).then(() => { if (!stopped) setReady(true); }).catch(onErr);
    } catch (e) { onErr(); }
    return () => { stopped = true; try { reader.reset(); } catch (e) {} };
  }, []);

  const submitManual = () => { const t = manual.trim(); if (t) { try { readerRef.current && readerRef.current.reset(); } catch (e) {} onDetected(t); } };

  return (
    <>
      <div className="scrim" style={{ zIndex: 80 }} onClick={onClose}></div>
      <div style={{ position: "fixed", left: "50%", top: "50%", transform: "translate(-50%, -50%)", zIndex: 81, background: "var(--surface)", border: "1px solid var(--line)", borderRadius: 14, padding: 16, width: "min(440px, 92vw)", boxShadow: "var(--shadow-lg)" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 12 }}>
          <I.qr size={18} />
          <div style={{ fontSize: 15, fontWeight: 700, flex: 1 }}>สแกนบาร์โค้ด</div>
          <button className="icon-btn" onClick={onClose}><I.close size={14} /></button>
        </div>
        {err ?
        <div style={{ padding: 14, background: "var(--danger-bg)", color: "var(--danger)", borderRadius: 8, fontSize: 13, lineHeight: 1.6 }}>{err}</div> :
        <div style={{ position: "relative", background: "#000", borderRadius: 10, overflow: "hidden", aspectRatio: "4 / 3" }}>
            <video ref={videoRef} autoPlay playsInline muted style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }}></video>
            <div style={{ position: "absolute", left: "8%", right: "8%", top: "50%", height: 2, background: "rgba(255,90,90,0.9)", boxShadow: "0 0 8px rgba(255,90,90,0.9)", transform: "translateY(-50%)" }}></div>
            <div style={{ position: "absolute", inset: "14% 8%", border: "2px solid rgba(255,255,255,0.85)", borderRadius: 12 }}></div>
            {!ready && <div style={{ position: "absolute", inset: 0, display: "grid", placeItems: "center", color: "#fff", fontSize: 13 }}>กำลังเปิดกล้อง…</div>}
          </div>
        }
        <div style={{ fontSize: 12, color: "var(--ink-3)", marginTop: 10, textAlign: "center" }}>เล็งกล้องไปที่บาร์โค้ดหรือ QR — ระบบอ่านอัตโนมัติ</div>
        <div style={{ display: "flex", gap: 8, marginTop: 12 }}>
          <input className="input" placeholder="หรือพิมพ์รหัสเอง…" value={manual} onChange={e => setManual(e.target.value)} onKeyDown={e => e.key === "Enter" && submitManual()}></input>
          <Btn kind="primary" onClick={submitManual}>ใช้รหัส</Btn>
        </div>
      </div>
    </>);

}

// ============ Barcode scan + print ============
function Barcode({ navigate }) {
  const D = window.SSSData;
  const { Btn, Card, PageHead, BarcodeVisual, fmt0 } = window.UI;
  const [scanned, setScanned] = useStateI(null);
  const [sku, setSku] = useStateI(D.Products.find(p => p.barcode !== "—")?.sku || "");
  const [count, setCount] = useStateI(20);
  const [orient, setOrient] = useStateI("landscape"); // landscape = 40×30 (แนวนอน) · portrait = 30×40 (แนวตั้ง)
  const [code, setCode] = useStateI("");
  const [scanning, setScanning] = useStateI(false);

  const selected = D.Products.find(p => p.sku === sku);
  const land = orient === "landscape"; // ป้ายแนวนอน 40×30

  const onScan = () => {
    const p = D.Products.find(p => p.barcode === code || p.sku === code);
    if (p) { setScanned(p); window.toast && window.toast("สแกนสำเร็จ: " + p.sku); }
    else window.toast && window.toast("ไม่พบสินค้า");
    setCode("");
  };

  // กล้องอ่านรหัสได้ → ค้นหาสินค้า
  const handleDetected = (text) => {
    setScanning(false);
    const t = String(text || "").trim();
    setCode(t);
    const p = D.Products.find(p => p.barcode === t || p.sku === t);
    if (p) { setScanned(p); window.toast && window.toast("สแกนสำเร็จ: " + p.name); }
    else window.toast && window.toast(`อ่านรหัสได้: ${t} — ไม่พบในระบบ`);
  };

  const printLabels = () => {
    if (!selected) return;
    // พิมพ์ลงสติกเกอร์ฉลากโดยตรง — 1 ดวงต่อ 1 หน้ากระดาษ (เครื่องพิมพ์ฉลาก/ลาเบล)
    const land = orient === "landscape";
    const PW = land ? 40 : 30, PH = land ? 30 : 40; // มม.
    const labelsHTML = [...Array(count)].map(() => `
      <div class="lbl">
        <div class="lbl-name">${selected.name.slice(0, 30)}</div>
        <div class="lbl-price">฿${selected.price.toLocaleString()}</div>
        <svg viewBox="0 0 100 24" preserveAspectRatio="none" class="lbl-bc">${generateBarcodeSVG(selected.barcode)}</svg>
        <div class="lbl-code">${selected.barcode}</div>
      </div>
    `).join("");
    document.getElementById("__print_modal")?.remove();
    document.body.classList.remove("printing-modal");
    const modal = document.createElement("div");
    modal.id = "__print_modal";
    modal.className = "print-modal";
    modal.innerHTML = `
      <div class="print-modal-bar no-print">
        <div style="display:flex;align-items:center;gap:12px;flex:1">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9V3h12v6"/><rect x="3" y="9" width="18" height="9" rx="2"/><rect x="6" y="14" width="12" height="7"/></svg>
          <span style="font-weight:600;font-size:14px">พิมพ์ป้ายบาร์โค้ด — สติกเกอร์ลาเบล ${PW}×${PH} มม. (${land ? "แนวนอน" : "แนวตั้ง"} · ${count} ดวง · 1 ดวง/แผ่น)</span>
        </div>
        <div style="display:flex;gap:8px">
          <button id="__print_close" class="pm-btn pm-btn-ghost">ปิด (Esc)</button>
          <button id="__print_btn" class="pm-btn pm-btn-primary">🖨 พิมพ์</button>
        </div>
      </div>
      <div class="print-modal-paper" style="padding:0;background:#e7e5e4">
        <style>
          /* บังคับขนาดกระดาษ = สติกเกอร์ ${PW}×${PH} มม. พอดี ไม่มีขอบ */
          @media print { @page { size: ${PW}mm ${PH}mm; margin: 0; } }
          .labels { display: flex; flex-direction: column; align-items: center; gap: 6mm; padding: 6mm 0; }
          .lbl { width: ${PW}mm; height: ${PH}mm; padding: ${land ? "1.6mm 1.5mm" : "1.8mm 1.5mm"}; display: flex; flex-direction: column; align-items: center; justify-content: space-between; box-sizing: border-box; color: #0c0a09; background: white; border: 0.4pt dashed #d6d3d1; }
          .lbl-name { font-size: ${land ? "6.5pt" : "7pt"}; font-weight: 500; text-align: center; line-height: 1.1; max-height: ${land ? "7mm" : "9mm"}; overflow: hidden; }
          .lbl-price { font-size: ${land ? "12pt" : "12pt"}; font-weight: 700; margin: 0; }
          .lbl-bc { width: ${land ? "36mm" : "26mm"}; height: ${land ? "9mm" : "8mm"}; display: block; }
          .lbl-code { font-family: monospace; font-size: ${land ? "6pt" : "6pt"}; letter-spacing: 0.5px; }
          @media print {
            .labels { display: block; gap: 0; padding: 0; }
            .lbl { border: 0; page-break-after: always; break-after: page; }
            .lbl:last-child { page-break-after: avoid; break-after: avoid; }
          }
        </style>
        <div class="labels">${labelsHTML}</div>
      </div>
    `;
    document.body.appendChild(modal);
    document.body.classList.add("printing-modal");
    const cleanup = () => { modal.remove(); document.body.classList.remove("printing-modal"); document.removeEventListener("keydown", onKey); };
    const onKey = (e) => { if (e.key === "Escape") cleanup(); };
    document.addEventListener("keydown", onKey);
    modal.addEventListener("click", e => { if (e.target === modal) cleanup(); });
    document.getElementById("__print_btn").addEventListener("click", () => window.print());
    document.getElementById("__print_close").addEventListener("click", cleanup);
  };

  return (
    <>
      <PageHead title="บาร์โค้ด · Barcode" sub="สแกนเพื่อค้นหา/นับสต็อก · พิมพ์ป้ายติดสินค้า"/>

      <div className="grid" style={{gridTemplateColumns: "1fr 1fr", gap: 14}}>
        <Card title="สแกนบาร์โค้ด" sub="ใช้กล้องโทรศัพท์/เครื่องสแกน หรือพิมพ์รหัส">
          <div style={{padding: 20, background: "var(--surface-2)", borderRadius: 10, border: "1.5px dashed var(--line-strong)", textAlign: "center", marginBottom: 12}}>
            <I.qr size={80} stroke="var(--ink-3)"/>
            <div style={{marginTop: 8, fontSize: 13, color: "var(--ink-3)"}}>เปิดกล้องเพื่อสแกน หรือพิมพ์รหัสด้านล่าง</div>
            <Btn icon={I.qr} kind="primary" size="sm" style={{marginTop: 10}} onClick={() => setScanning(true)}>เปิดกล้องสแกน</Btn>
          </div>
          <div style={{display: "flex", gap: 8}}>
            <input className="input" placeholder="พิมพ์ / Scan barcode (เช่น 8851000010012)" value={code} onChange={e=>setCode(e.target.value)} onKeyDown={e=>e.key==='Enter'&&onScan()}/>
            <Btn kind="primary" onClick={onScan}>ค้นหา</Btn>
          </div>
          <div style={{marginTop: 12}}>
            <div className="label mb">บาร์โค้ดตัวอย่าง (คลิกเพื่อทดลอง)</div>
            <div style={{display: "flex", gap: 6, flexWrap: "wrap"}}>
              {D.Products.filter(p => p.barcode !== "—").slice(0, 5).map(p => (
                <button key={p.sku} className="btn sm ghost" style={{fontFamily: "var(--font-mono)", fontSize: 11}}
                  onClick={() => { setCode(p.barcode); setScanned(p); }}>{p.barcode}</button>
              ))}
            </div>
          </div>

          {scanned && (
            <div style={{marginTop: 14, padding: 14, background: "var(--success-bg)", borderRadius: 8, border: "1px solid var(--success)"}}>
              <div style={{display: "flex", justifyContent: "space-between", alignItems: "flex-start"}}>
                <div>
                  <div style={{fontSize: 12, color: "var(--success)", fontWeight: 600, marginBottom: 2}}>✓ สแกนสำเร็จ</div>
                  <div style={{fontWeight: 600, fontSize: 14}}>{scanned.name}</div>
                  <div className="mono muted" style={{fontSize: 12}}>{scanned.sku} · ตำแหน่ง {scanned.location}</div>
                  <div style={{marginTop: 6, fontSize: 12}}>คงเหลือ <b>{scanned.stock} {scanned.unit}</b> · ราคา ฿{fmt0(scanned.price)}</div>
                </div>
                <div style={{display: "flex", flexDirection: "column", gap: 4}}>
                  <Btn size="sm">+ เพิ่มเข้า</Btn>
                  <Btn size="sm">− เบิกออก</Btn>
                </div>
              </div>
            </div>
          )}
        </Card>

        <Card title="พิมพ์ป้ายบาร์โค้ด" sub="ขนาดมาตรฐาน 30×40 มม. (สำหรับสติกเกอร์หรือเครื่องพิมพ์ฉลาก)">
          <div className="field mb"><label>เลือกสินค้า</label>
            <select className="input" value={sku} onChange={e=>setSku(e.target.value)}>
              {D.Products.filter(p => p.barcode !== "—").map(p => <option key={p.sku} value={p.sku}>{p.sku} — {p.name}</option>)}
            </select>
          </div>
          <div className="field-row cols-2 mb">
            <div className="field"><label>จำนวนป้าย</label><input className="input" type="number" min="1" value={count} onChange={e=>setCount(Math.max(1, +e.target.value || 1))}/></div>
            <div className="field"><label>แนววางป้าย / ขนาด</label>
              <select className="input" value={orient} onChange={e=>setOrient(e.target.value)}>
                <option value="landscape">แนวนอน · 40 × 30 มม.</option>
                <option value="portrait">แนวตั้ง · 30 × 40 มม.</option>
              </select>
            </div>
          </div>
          <div className="label mb">ตัวอย่างป้าย (พิมพ์ตามจำนวนที่ระบุ)</div>
          <div style={{background: "white", padding: 14, borderRadius: 8, border: "1px solid var(--line)", display: "flex", flexWrap: "wrap", gap: 10}}>
            {selected && [...Array(Math.min(count, 6))].map((_, i) => (
              <div key={i} style={{
                width: land ? 151 : 113, height: land ? 113 : 151,
                padding: land ? "7px 6px" : 6,
                border: "1px dashed #d6d3d1",
                borderRadius: 3,
                background: "white",
                color: "#0c0a09",
                display: "flex",
                flexDirection: "column",
                alignItems: "center",
                justifyContent: "space-between",
                textAlign: "center"
              }}>
                <div style={{fontSize: land ? 8.5 : 9, fontWeight: 500, lineHeight: 1.1, maxHeight: land ? 24 : 30, overflow: "hidden"}}>{selected.name.slice(0, 28)}</div>
                <div style={{fontSize: land ? 16 : 16, fontWeight: 700}}>฿{fmt0(selected.price)}</div>
                <BarcodeVisual code={selected.barcode} width={land ? 138 : 96} height={land ? 34 : 28}/>
              </div>
            ))}
          </div>
          <div style={{marginTop: 8, fontSize: 11, color: "var(--ink-3)"}}>แสดง {Math.min(count, 6)} ป้ายแรก · พิมพ์จริง {count} ดวง — 1 ดวงต่อ 1 สติกเกอร์ลาเบล {land ? "40 × 30 มม. (แนวนอน)" : "30 × 40 มม. (แนวตั้ง)"} · เครื่องพิมพ์ฉลาก</div>
          <div style={{marginTop: 12, display: "flex", gap: 8, justifyContent: "flex-end"}}>
            <Btn icon={I.print} kind="primary" onClick={printLabels}>พิมพ์ {count} ป้าย</Btn>
          </div>
        </Card>
      </div>
      {scanning && <BarcodeScanModal onClose={() => setScanning(false)} onDetected={handleDetected} />}
    </>
  );
}

// Helper: barcode SVG bars (deterministic from code)
function generateBarcodeSVG(code) {
  if (!code) return "";
  let seed = 0;
  for (let i = 0; i < code.length; i++) seed += code.charCodeAt(i);
  let r = seed, x = 0, i = 0;
  const bars = [];
  // เติมแท่งบาร์โค้ดให้เต็มความกว้าง viewBox (0–100) — บาร์โค้ดจึงอยู่กึ่งกลางป้ายพอดี
  while (x < 100) {
    r = (r * 9301 + 49297) % 233280;
    const w = (r % 4 + 1) * 0.7;
    if (i % 2 === 0) {
      const ww = Math.min(w, 100 - x);
      bars.push(`<rect x="${x.toFixed(2)}" y="0" width="${ww.toFixed(2)}" height="24" fill="#0c0a09"/>`);
    }
    x += w + 0.5;
    i++;
  }
  return bars.join("");
}

window.CameraCaptureModal = CameraCaptureModal;
window.InventoryProducts = InventoryProducts;
window.StockMovements = StockMovements;
window.Barcode = Barcode;
