/* global React, Ic, useStore, useToast, Modal, AnimNumber, Sparkline, fireConfetti */
const { useState: useIS, useMemo: useIM } = React;

// ========= Item Master =========
function PageItems({ onOpenItem }) {
  const store = useStore();
  const { state, setState } = store;
  const toast = useToast();
  const [q, setQ] = useIS('');
  const [cat, setCat] = useIS('all');
  const [stockFilter, setStockFilter] = useIS('all'); // all | out | low | ok
  const [view, setView] = useIS('table'); // table | grid
  const [addOpen, setAddOpen] = useIS(false);
  const [form, setForm] = useIS({ sku: '', name_th: '', name: '', category: '', uom: 'PCS', unit_cost: 0, unit_price: 0, min: 10, max: 100, supplier: '', barcode: '', shelfLife: 365 });

  const cats = ['all', ...new Set(state.items.map(i => i.category))];

  const totals = useIM(() => {
    const m = {};
    state.stock.forEach(s => { m[s.sku] = (m[s.sku] || 0) + s.qty; });
    return m;
  }, [state.stock]);

  const items = [...state.items].sort(cmpItem).filter(i => {
    const matchQ = !q || i.sku.toLowerCase().includes(q.toLowerCase()) || (i.name_th || '').toLowerCase().includes(q.toLowerCase()) || (i.name || '').toLowerCase().includes(q.toLowerCase()) || (i.barcode || '').includes(q);
    const matchC = cat === 'all' || i.category === cat;
    const qty = totals[i.sku] || 0;
    let matchS = true;
    if (stockFilter === 'out') matchS = qty === 0;
    else if (stockFilter === 'low') matchS = qty > 0 && qty < i.min;
    else if (stockFilter === 'ok') matchS = qty >= i.min;
    return matchQ && matchC && matchS;
  });

  const outCount = state.items.filter(i => (totals[i.sku] || 0) === 0).length;

  const addItem = () => {
    if (!form.sku || !form.name_th) { toast.error('กรอกข้อมูลให้ครบ'); return; }
    const sku = String(form.sku).trim();
    const dup = state.items.find(i => i.sku === sku);
    if (dup) { toast.error('SKU นี้มีอยู่แล้ว', `${sku} · ${dup.name_th} — ใช้ปุ่มแก้ไขแทน`); return; }
    // Auto-register the supplier if it's a new name
    if (form.supplier && !state.suppliers.find(sp => sp.name === form.supplier)) {
      store.addSupplier(form.supplier);
    }
    setState(s => {
      if (s.items.find(i => i.sku === sku)) return s; // duplicate guard (state may have changed)
      return { ...s, items: [...s.items, { ...form, sku, unit_cost: Number(form.unit_cost), unit_price: Number(form.unit_price), min: Number(form.min), max: Number(form.max), shelfLife: Number(form.shelfLife) || 0 }] };
    });
    toast.success('เพิ่มสินค้าใหม่', form.name_th);
    fireConfetti();
    setAddOpen(false);
    setForm({ sku: '', name_th: '', name: '', category: '', uom: 'PCS', unit_cost: 0, unit_price: 0, min: 10, max: 100, supplier: '', barcode: '', shelfLife: 365 });
  };

  const tryDelete = (e, item) => {
    e.stopPropagation();
    const check = store.canDeleteItem(item.sku);
    if (!check.ok) { toast.error('ลบสินค้าไม่ได้', `ยังมีสต็อก ${check.totalQty} units อยู่`); return; }
    if (!confirm(`ลบสินค้า ${item.sku} (${item.name_th}) ?`)) return;
    store.deleteItem(item.sku);
    toast.success('ลบสินค้าแล้ว', `${item.sku} · ${item.name_th}`);
  };

  return (
    <div className="page-enter">
      <div className="page-header">
        <div>
          <h2 className="page-title">รายการสินค้า <span className="muted mono" style={{fontSize:14, marginLeft:8}}>// ITEM MASTER</span></h2>
          <div className="page-subtitle">จัดการ SKU master · {items.length} / {state.items.length} items</div>
        </div>
        <div className="row">
          <div className="segmented">
            <button className={view==='table'?'active':''} onClick={()=>setView('table')}>Table</button>
            <button className={view==='grid'?'active':''} onClick={()=>setView('grid')}>Grid</button>
          </div>
          <button className="btn btn-ghost" onClick={() => downloadCSV('item-master.csv',
            ['SKU','ชื่อสินค้า (TH)','Name (EN)','หมวด','UoM','ต้นทุน','ราคาขาย','Min','Max','คงเหลือ','Supplier','Barcode','ShelfLife (วัน)'],
            items.map(i => [i.sku, i.name_th, i.name, i.category, i.uom, i.unit_cost, i.unit_price, i.min, i.max, (totals[i.sku] || 0), i.supplier, i.barcode, i.shelfLife])
          )}><Ic name="export" size={14}/>Export CSV</button>
          <button className="btn btn-primary" onClick={() => setAddOpen(true)}><Ic name="plus" size={14}/>เพิ่มสินค้าใหม่</button>
        </div>
      </div>

      <div className="card tech" style={{ padding: 12, marginBottom: 14 }}>
        <div className="row" style={{ gap: 10, flexWrap: 'wrap' }}>
          <div className="searchbar" style={{ flex: 1, maxWidth: 'none', borderRadius: 8, minWidth: 240 }}>
            <Ic name="search" size={14}/>
            <input placeholder="ค้นหา SKU, ชื่อ, barcode..." value={q} onChange={e => setQ(e.target.value)}/>
          </div>
          <div className="segmented">
            {cats.map(c => <button key={c} className={cat === c ? 'active' : ''} onClick={() => setCat(c)}>{c === 'all' ? 'ทั้งหมด' : c}</button>)}
          </div>
          <div className="segmented">
            <button className={stockFilter==='all'?'active':''} onClick={()=>setStockFilter('all')}>STOCK · ALL</button>
            <button className={stockFilter==='ok'?'active':''} onClick={()=>setStockFilter('ok')}>OK</button>
            <button className={stockFilter==='low'?'active':''} onClick={()=>setStockFilter('low')}>LOW</button>
            <button className={stockFilter==='out'?'active':''} onClick={()=>setStockFilter('out')}>
              OUT {outCount > 0 && <span className="mono" style={{marginLeft:4, color:'var(--danger)'}}>· {outCount}</span>}
            </button>
          </div>
        </div>
      </div>

      {view === 'table' && (
        <div className="card tech" style={{ padding: 0 }}>
          <div className="table-wrap" style={{ border: 'none', borderRadius: 14 }}>
            <table className="data">
              <thead>
                <tr>
                  <th>SKU</th>
                  <th>ชื่อสินค้า</th>
                  <th>หมวด</th>
                  <th style={{ textAlign: 'right' }}>คงเหลือ</th>
                  <th style={{ textAlign: 'right' }}>Min / Max</th>
                  <th style={{ textAlign: 'right' }}>ต้นทุน</th>
                  <th style={{ textAlign: 'right' }}>ราคา</th>
                  <th>Status</th>
                  <th></th>
                </tr>
              </thead>
              <tbody>
                {items.map(i => {
                  const qty = totals[i.sku] || 0;
                  const status = qty === 0 ? 'crit' : qty < i.min ? 'warn' : qty > i.max * 0.95 ? 'info' : 'ok';
                  const statusLabel = qty === 0 ? 'OUT' : qty < i.min ? 'LOW' : qty > i.max * 0.95 ? 'FULL' : 'OK';
                  return (
                    <tr key={i.sku} className="clickable item-row" onClick={() => onOpenItem(i.sku)}>
                      <td className="mono" style={{ color: 'var(--accent)' }}>{i.sku}</td>
                      <td>{i.name_th}<div className="mono" style={{ fontSize: 10.5, color: 'var(--text-muted)' }}>{i.name}</div></td>
                      <td><span className="badge neutral">{i.category}</span></td>
                      <td className="num" style={{ color: qty === 0 ? 'var(--text-muted)' : undefined }}>{qty.toLocaleString()}</td>
                      <td className="num" style={{ color: 'var(--text-muted)' }}>{i.min} / {i.max}</td>
                      <td className="num">฿{i.unit_cost}</td>
                      <td className="num">฿{i.unit_price}</td>
                      <td><span className={`badge ${status}`}>{statusLabel}</span></td>
                      <td style={{ width: 70, textAlign: 'right' }}>
                        <div className="row" style={{ gap: 4, justifyContent: 'flex-end' }}>
                          <button className="row-action danger" onClick={(e) => tryDelete(e, i)}
                            disabled={qty > 0}
                            data-tip={qty > 0 ? `ยังมีสต็อก ${qty} units` : 'ลบสินค้า'}>
                            <Ic name="trash" size={12}/>
                          </button>
                          <Ic name="chevron-right" size={14} style={{ color: 'var(--text-muted)' }}/>
                        </div>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </div>
      )}

      {view === 'grid' && (
        <div className="grid-4">
          {items.map(i => {
            const qty = totals[i.sku] || 0;
            const pct = Math.min(100, (qty / i.max) * 100);
            const status = qty === 0 ? 'crit' : qty < i.min ? 'warn' : 'ok';
            return (
              <div key={i.sku} className="card hover tech" onClick={() => onOpenItem(i.sku)} style={{ cursor: 'pointer' }}>
                <div className="row" style={{ justifyContent: 'space-between', marginBottom: 10 }}>
                  <span className="mono" style={{ fontSize: 11, color: 'var(--accent)' }}>{i.sku}</span>
                  <span className={`badge ${status}`}>{status === 'crit' ? 'OUT' : status === 'warn' ? 'LOW' : 'OK'}</span>
                </div>
                <div className="thumb thumb-md" style={{ width: '100%' }}><Ic name="package" size={32}/></div>
                <div style={{ marginTop: 12, fontSize: 13.5, lineHeight: 1.3 }}>{i.name_th}</div>
                <div className="mono" style={{ fontSize: 10.5, color: 'var(--text-muted)', marginTop: 4 }}>{i.category} · {i.uom}</div>
                <div style={{ marginTop: 10, height: 4, background: 'var(--bg-card-2)', borderRadius: 4, overflow: 'hidden' }}>
                  <div style={{ width: `${pct}%`, height: '100%', background: status === 'crit' ? 'var(--danger)' : status === 'warn' ? 'var(--warning)' : 'linear-gradient(90deg, var(--accent), var(--success))' }}/>
                </div>
                <div className="row" style={{ marginTop: 8, justifyContent: 'space-between' }}>
                  <span className="mono" style={{ fontSize: 11, color: 'var(--text-muted)' }}>คงเหลือ</span>
                  <span className="mono" style={{ fontSize: 14, color: 'var(--accent)' }}>{qty.toLocaleString()}</span>
                </div>
              </div>
            );
          })}
        </div>
      )}

      <Modal open={addOpen} onClose={() => setAddOpen(false)} title="เพิ่มสินค้าใหม่"
        footer={(
          <>
            <button className="btn btn-ghost" onClick={() => setAddOpen(false)}>ยกเลิก</button>
            <button className="btn btn-primary" onClick={addItem}><Ic name="check" size={14}/>บันทึก SKU ใหม่</button>
          </>
        )}>
        <ItemFormFields form={form} setForm={setForm}/>
      </Modal>
    </div>
  );
}

// Shared item form fields (used by Add and Edit item modals)
function ItemFormFields({ form, setForm, lockSku }) {
  return (
    <div className="grid-2">
      <div className="field"><label>SKU</label><input className="input mono" value={form.sku} disabled={lockSku} onChange={e => setForm({...form, sku: e.target.value})} placeholder="EL-1006"/></div>
      <div className="field"><label>Barcode</label><input className="input mono" value={form.barcode} onChange={e => setForm({...form, barcode: e.target.value})} placeholder="885xxxxxxxxxx"/></div>
      <div className="field" style={{ gridColumn: '1 / 3' }}><label>ชื่อสินค้า (ไทย)</label><input className="input" value={form.name_th} onChange={e => setForm({...form, name_th: e.target.value})}/></div>
      <div className="field" style={{ gridColumn: '1 / 3' }}><label>Name (English)</label><input className="input" value={form.name} onChange={e => setForm({...form, name: e.target.value})}/></div>
      <div className="field"><label>หมวด</label><CategoryPicker value={form.category} onChange={v => setForm({...form, category: v})}/></div>
      <div className="field"><label>หน่วย / UoM</label>
        <select className="select" value={form.uom} onChange={e => setForm({...form, uom: e.target.value})}>
          {['PCS','REAM','PACK','BOX','SET'].map(u => <option key={u}>{u}</option>)}
        </select>
      </div>
      <div className="field"><label>ต้นทุน (฿)</label><input className="input mono" type="number" value={form.unit_cost} onChange={e => setForm({...form, unit_cost: e.target.value})}/></div>
      <div className="field"><label>ราคาขาย (฿)</label><input className="input mono" type="number" value={form.unit_price} onChange={e => setForm({...form, unit_price: e.target.value})}/></div>
      <div className="field"><label>Min Qty</label><input className="input mono" type="number" value={form.min} onChange={e => setForm({...form, min: e.target.value})}/></div>
      <div className="field"><label>Max Qty</label><input className="input mono" type="number" value={form.max} onChange={e => setForm({...form, max: e.target.value})}/></div>
      <div className="field" style={{ gridColumn: '1 / 3' }}><label>Supplier · ผู้ผลิต/ผู้จัดจำหน่าย</label>
        <SupplierPicker value={form.supplier} onChange={v => setForm({...form, supplier: v})}/>
      </div>
      <div className="field" style={{ gridColumn: '1 / 3' }}>
        <label>Shelf Life · อายุสินค้าหลังผลิต (วัน)</label>
        <div className="row" style={{ gap: 8 }}>
          <input className="input mono" type="number" min="0" style={{ flex: 1 }}
            value={form.shelfLife} onChange={e => setForm({...form, shelfLife: e.target.value})} placeholder="365"/>
          <div className="segmented">
            {[
              { label: '14d', v: 14 }, { label: '90d', v: 90 }, { label: '6ม', v: 180 },
              { label: '1ป', v: 365 }, { label: '2ป', v: 730 }, { label: '3ป', v: 1095 }, { label: '4ป', v: 1460 },
            ].map(p => (
              <button key={p.v} type="button"
                className={Number(form.shelfLife) === p.v ? 'active' : ''}
                onClick={() => setForm({...form, shelfLife: p.v})}>{p.label}</button>
            ))}
          </div>
        </div>
        <div className="mono" style={{ fontSize: 10.5, color: 'var(--text-muted)', marginTop: 4 }}>
          ≈ {fmtShelfLife(Number(form.shelfLife))} · ใส่ 0 ถ้าสินค้าไม่มีวันหมดอายุ
        </div>
      </div>
    </div>
  );
}

// Edit existing item (reuses ItemFormFields; SKU locked)
function EditItemModal({ sku, onClose }) {
  const store = useStore();
  const toast = useToast();
  const item = store.state.items.find(i => i.sku === sku);
  const [form, setForm] = useIS(() => (item ? { ...item } : null));
  if (!item || !form) return null;
  const save = () => {
    if (!String(form.name_th).trim()) { toast.error('กรอกชื่อสินค้า'); return; }
    if (form.supplier && !store.state.suppliers.find(sp => sp.name === form.supplier)) store.addSupplier(form.supplier);
    if (form.category && !(store.state.categories || []).find(c => c.name === form.category)) store.addCategory(form.category);
    store.updateItem(sku, {
      ...form, sku,
      unit_cost: Number(form.unit_cost), unit_price: Number(form.unit_price),
      min: Number(form.min), max: Number(form.max), shelfLife: Number(form.shelfLife) || 0,
    });
    toast.success('บันทึกสินค้า', form.name_th);
    onClose();
  };
  return (
    <Modal open onClose={onClose} title={`แก้ไขสินค้า · ${sku}`}
      footer={(
        <>
          <button className="btn btn-ghost" onClick={onClose}>ยกเลิก</button>
          <button className="btn btn-primary" onClick={save}><Ic name="check" size={14}/>บันทึก</button>
        </>
      )}>
      <ItemFormFields form={form} setForm={setForm} lockSku/>
    </Modal>
  );
}

// ========= Item Detail =========
function PageItemDetail({ sku, onBack }) {
  const store = useStore();
  const { state } = store;
  const toast = useToast();
  const item = state.items.find(i => i.sku === sku);
  if (!item) return <div className="empty"><Ic name="alert" size={28}/>ไม่พบสินค้า</div>;

  const stocks = state.stock.filter(s => s.sku === sku);
  const totalQty = stocks.reduce((a, b) => a + b.qty, 0);
  const totalValue = totalQty * item.unit_cost;
  const movements = state.movements.filter(m => m.sku === sku).slice(0, 30);
  const canDel = totalQty === 0;
  const [editOpen, setEditOpen] = useIS(false);

  const tryDelete = () => {
    if (!canDel) { toast.error('ลบสินค้าไม่ได้', `ยังมีสต็อก ${totalQty} units อยู่`); return; }
    if (!confirm(`ลบสินค้า ${item.sku} (${item.name_th}) ?\n\nสินค้านี้จะถูกลบออกจาก Item Master ทั้งหมด`)) return;
    store.deleteItem(item.sku);
    toast.success('ลบสินค้าแล้ว', `${item.sku} · ${item.name_th}`);
    onBack();
  };

  // 30-day series
  const series = useIM(() => {
    const days = 30;
    const today = new Date(); today.setHours(0,0,0,0);
    const inS = Array(days).fill(0);
    const outS = Array(days).fill(0);
    movements.forEach(m => {
      const d = new Date(m.ts); d.setHours(0,0,0,0);
      const diff = Math.floor((today - d) / 86400000);
      if (diff >= 0 && diff < days) {
        if (m.type === 'IN') inS[days - 1 - diff] += m.qty;
        if (m.type === 'OUT') outS[days - 1 - diff] += m.qty;
      }
    });
    return { inS, outS };
  }, [movements]);

  const status = totalQty === 0 ? 'crit' : totalQty < item.min ? 'warn' : 'ok';

  return (
    <div className="page-enter">
      <div className="row" style={{ marginBottom: 12 }}>
        <button className="btn btn-ghost btn-sm" onClick={onBack}><Ic name="chevron-left" size={12}/>กลับสู่รายการสินค้า</button>
        <span className="muted mono" style={{ fontSize: 11 }}>/ ITEMS / {sku}</span>
      </div>

      <div className="grid-2" style={{ gridTemplateColumns: '300px 1fr', gap: 18, alignItems: 'flex-start' }}>
        <div className="card tech" style={{ position: 'sticky', top: 0 }}>
          <div className="thumb thumb-lg" style={{ width: '100%', height: 220, marginBottom: 14 }}><Ic name="package" size={48}/></div>
          <div className="row" style={{ justifyContent: 'space-between' }}>
            <span className="mono" style={{ color: 'var(--accent)', fontSize: 12 }}>{item.sku}</span>
            <span className={`badge ${status}`}>{status === 'crit' ? 'OUT' : status === 'warn' ? 'LOW' : 'OK'}</span>
          </div>
          <h3 style={{ marginTop: 6, fontSize: 18, lineHeight: 1.3 }}>{item.name_th}</h3>
          <div className="mono" style={{ color: 'var(--text-muted)', fontSize: 11.5, marginBottom: 14 }}>{item.name}</div>

          <div style={{ display: 'flex', flexDirection: 'column', gap: 8, fontSize: 12.5 }}>
            <KV label="หมวด" value={item.category}/>
            <KV label="หน่วย" value={item.uom}/>
            <KV label="Supplier" value={item.supplier}/>
            <KV label="Barcode" value={item.barcode} mono/>
            <div className="hr"/>
            <KV label="ต้นทุน" value={`฿${item.unit_cost}`} mono/>
            <KV label="ราคาขาย" value={`฿${item.unit_price}`} mono/>
            <KV label="Min · Max" value={`${item.min} · ${item.max}`} mono/>
            <div className="hr"/>
            <KV label="Shelf Life" value={item.shelfLife ? fmtShelfLife(item.shelfLife) : 'ไม่ติดตามอายุ'} mono/>
          </div>

          <div className="row" style={{ marginTop: 14, gap: 8 }}>
            <button className="btn btn-ghost btn-sm" style={{ flex: 1, justifyContent: 'center' }} onClick={() => setEditOpen(true)}><Ic name="edit" size={12}/>แก้ไข</button>
            <button className="btn btn-ghost btn-sm" style={{ flex: 1, justifyContent: 'center' }}><Ic name="qr" size={12}/>QR</button>
          </div>
          <button className="btn btn-danger btn-sm" onClick={tryDelete} disabled={!canDel}
            data-tip={!canDel ? `ยังมีสต็อก ${totalQty} units อยู่` : undefined}
            style={{ marginTop: 8, width: '100%', justifyContent: 'center' }}>
            <Ic name="trash" size={12}/>ลบสินค้าออกจาก Master
          </button>
          {!canDel && (
            <div className="mono" style={{ marginTop: 6, fontSize: 10.5, color: 'var(--warning)', textAlign: 'center' }}>
              ⚠ จ่ายออกให้เหลือ 0 ก่อนจึงจะลบได้
            </div>
          )}
          {canDel && totalQty === 0 && stocks.length > 0 && (
            <div className="mono" style={{ marginTop: 6, fontSize: 10.5, color: 'var(--text-muted)', textAlign: 'center' }}>
              ยอดคงเหลือ 0 · พร้อมลบได้
            </div>
          )}
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          {/* KPI strip */}
          <div className="grid-4">
            <MiniKPI label="ยอดคงเหลือรวม" value={totalQty} suffix=" units" color="var(--accent)"/>
            <MiniKPI label="มูลค่าคงคลัง" value={totalValue} prefix="฿" color="var(--info)"/>
            <MiniKPI label="กระจายอยู่" value={stocks.length} suffix=" locs" color="var(--purple)"/>
            <MiniKPI label="เคลื่อนไหว 30D" value={movements.reduce((a,b)=>a+b.qty,0)} suffix=" u" color="var(--success)"/>
          </div>

          {/* Movement chart */}
          <div className="card tech">
            <div className="card-head">
              <div>
                <div className="card-title">เคลื่อนไหว 30 วันล่าสุด</div>
                <div className="card-sub">QTY · UNIT_MOVED</div>
              </div>
              <div className="row" style={{ gap: 12 }}>
                <span className="lead-dot" style={{ color: 'var(--accent)' }}>IN</span>
                <span className="lead-dot" style={{ color: 'var(--warning)' }}>OUT</span>
              </div>
            </div>
            <ItemMovementChart inSeries={series.inS} outSeries={series.outS}/>
          </div>

          {/* Stock by location */}
          <div className="card tech">
            <div className="card-head">
              <div>
                <div className="card-title">คงเหลือแต่ละ Location</div>
                <div className="card-sub">PER_LOCATION · {stocks.length} LOCS</div>
              </div>
            </div>
            <div className="table-wrap" style={{ border: 'none' }}>
              <table className="data">
                <thead>
                  <tr><th>Location</th><th>Zone</th><th>LOT</th><th>MFG</th><th>EXPIRY</th><th style={{textAlign:'right'}}>Qty</th><th style={{textAlign:'right'}}>% of total</th></tr>
                </thead>
                <tbody>
                  {[...stocks].sort((a,b) => (a.expiry || Infinity) - (b.expiry || Infinity)).map(s => {
                    const loc = state.locations.find(l => l.id === s.locId);
                    const pct = (s.qty / totalQty) * 100;
                    const st = expiryStatus(s.expiry);
                    return (
                      <tr key={s.locId + s.lot}>
                        <td className="mono" style={{ color: 'var(--accent)' }}><Ic name="pin" size={11} style={{ display: 'inline', marginRight: 4, opacity: 0.6 }}/>{s.locId}</td>
                        <td>{loc?.zone} · {loc?.zoneName}</td>
                        <td className="mono" style={{ color: 'var(--text-muted)' }}>{s.lot}</td>
                        <td className="mono" style={{ fontSize: 11, color: 'var(--text-muted)' }}>{fmtDate(s.mfgDate)}</td>
                        <td>
                          {s.expiry ? (
                            <div className="row" style={{ gap: 6 }}>
                              <span className="mono" style={{ fontSize: 11, color: st.cls === 'expired' || st.cls === 'crit' ? 'var(--danger)' : 'var(--text-primary)' }}>{fmtDate(s.expiry)}</span>
                              <span className={`badge ${st.badge}`}>{st.label}</span>
                            </div>
                          ) : <span className="mono" style={{ fontSize: 11, color: 'var(--text-dim)' }}>—</span>}
                        </td>
                        <td className="num">{s.qty}</td>
                        <td>
                          <div className="row" style={{ gap: 8, justifyContent: 'flex-end' }}>
                            <div style={{ width: 70, height: 4, background: 'var(--bg-card-2)', borderRadius: 4, overflow: 'hidden' }}>
                              <div style={{ width: `${pct}%`, height: '100%', background: 'var(--accent)' }}/>
                            </div>
                            <span className="mono" style={{ fontSize: 11, minWidth: 38, textAlign: 'right' }}>{pct.toFixed(1)}%</span>
                          </div>
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          </div>

          {/* Movement history */}
          <div className="card tech">
            <div className="card-head">
              <div className="card-title">ประวัติการเคลื่อนไหว</div>
              <span className="mono" style={{ fontSize: 11, color: 'var(--text-muted)' }}>{movements.length} entries</span>
            </div>
            <div className="table-wrap" style={{ border: 'none' }}>
              <table className="data">
                <thead><tr><th>Type</th><th>Time</th><th>Ref</th><th>From</th><th>To</th><th style={{textAlign:'right'}}>Qty</th><th>By</th></tr></thead>
                <tbody>
                  {movements.slice(0, 12).map(m => (
                    <tr key={m.id}>
                      <td><MovementBadge type={m.type}/></td>
                      <td className="mono" style={{ fontSize: 11 }}>{new Date(m.ts).toLocaleString('th-TH')}</td>
                      <td className="mono" style={{ color: 'var(--accent)' }}>{m.ref}</td>
                      <td className="mono" style={{ fontSize: 11 }}>{m.from?.slice(-9) || '—'}</td>
                      <td className="mono" style={{ fontSize: 11 }}>{m.type === 'OUT' ? (m.customer || m.to || '—') : (m.to?.slice(-9) || '—')}</td>
                      <td className="num">{m.delta !== undefined ? (m.delta > 0 ? '+' : '') + m.delta : m.qty}</td>
                      <td style={{ fontSize: 11.5, color: 'var(--text-muted)' }}>{m.user}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>
        </div>
      </div>
      {editOpen && <EditItemModal sku={sku} onClose={() => setEditOpen(false)}/>}
    </div>
  );
}

function KV({ label, value, mono }) {
  return (
    <div className="row" style={{ justifyContent: 'space-between' }}>
      <span style={{ color: 'var(--text-muted)' }}>{label}</span>
      <span className={mono ? 'mono' : ''} style={{ color: 'var(--text-primary)', fontSize: mono ? 12 : undefined }}>{value}</span>
    </div>
  );
}

function MiniKPI({ label, value, prefix, suffix, color }) {
  return (
    <div className="card tech" style={{ padding: 14 }}>
      <div className="mono" style={{ fontSize: 10.5, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: 6 }}>{label}</div>
      <div className="mono" style={{ fontSize: 20, color, fontWeight: 700 }}>
        <AnimNumber value={value} prefix={prefix} suffix={suffix}/>
      </div>
    </div>
  );
}

function MovementBadge({ type }) {
  const map = { IN: { cls: 'ok', ic: 'arrow-down', label: 'IN' }, OUT: { cls: 'warn', ic: 'arrow-up', label: 'OUT' }, TRANSFER: { cls: 'info', ic: 'transfer', label: 'TR' }, COUNT: { cls: 'purple', ic: 'count', label: 'CT' } };
  const m = map[type] || map.IN;
  return <span className={`badge ${m.cls}`}><Ic name={m.ic} size={10}/>{m.label}</span>;
}

function ItemMovementChart({ inSeries, outSeries }) {
  const w = 700, h = 160, pad = 26;
  const max = Math.max(...inSeries, ...outSeries, 10);
  const bw = (w - pad * 2) / inSeries.length;
  return (
    <svg viewBox={`0 0 ${w} ${h}`} style={{ width: '100%', height: 180 }}>
      {[0.25, 0.5, 0.75].map((p, i) => (
        <line key={i} x1={pad} x2={w-pad} y1={pad + (h-pad*2)*p} y2={pad + (h-pad*2)*p} stroke="var(--border)" strokeDasharray="2 4"/>
      ))}
      {inSeries.map((v, i) => {
        const x = pad + i * bw;
        const ih = (v / max) * (h - pad * 2);
        const o = outSeries[i];
        const oh = (o / max) * (h - pad * 2);
        return (
          <g key={i}>
            {ih > 0 && <rect className="bar" x={x + 2} y={h - pad - ih} width={bw * 0.4 - 2} height={ih} fill="#22d3ee" rx="2" style={{ animationDelay: `${i * 0.03}s` }}/>}
            {oh > 0 && <rect className="bar" x={x + bw * 0.5} y={h - pad - oh} width={bw * 0.4 - 2} height={oh} fill="#f5b32a" rx="2" style={{ animationDelay: `${i * 0.03 + 0.1}s` }}/>}
          </g>
        );
      })}
    </svg>
  );
}

// ========= Locations + Warehouse Map (Multi-Warehouse) =========
function PageLocations() {
  const store = useStore();
  const { state, setState } = store;
  const toast = useToast();
  const cwh = store.currentWarehouse();

  const [selectedZone, setSelectedZone] = useIS(cwh.zones[0].zone);
  const [addOpen, setAddOpen] = useIS(false);
  const [addWhOpen, setAddWhOpen] = useIS(false);
  const [editWh, setEditWh] = useIS(null); // wh object being edited
  const [editLoc, setEditLoc] = useIS(null); // location object being edited
  const [zoneNameEdit, setZoneNameEdit] = useIS(null); // draft name while renaming a zone (null = not editing)
  const [form, setForm] = useIS({ zone: cwh.zones[0].zone, rack: '07', shelf: '1' });
  const [whForm, setWhForm] = useIS({ id: '', name: '', city: '', address: '', kind: 'คลังเจ้านาง' });

  // Reset selected zone when warehouse changes
  React.useEffect(() => {
    if (!cwh.zones.find(z => z.zone === selectedZone)) {
      setSelectedZone(cwh.zones[0].zone);
    }
    setForm(f => ({ ...f, zone: cwh.zones[0].zone }));
  }, [cwh.id]);

  // Per-warehouse stats for the switcher strip
  const allWhStats = useIM(() => {
    return state.warehouses.map(wh => {
      const locs = state.locations.filter(l => l.wh === wh.id);
      const locIds = new Set(locs.map(l => l.id));
      const stock = state.stock.filter(s => locIds.has(s.locId));
      const totalQty = stock.reduce((a, b) => a + b.qty, 0);
      const skuCount = new Set(stock.map(s => s.sku)).size;
      const capacity = locs.length * 200;
      return { ...wh, locCount: locs.length, totalQty, skuCount, capacity, util: Math.min(100, (totalQty / capacity) * 100) };
    });
  }, [state]);

  // Zones for the current warehouse
  const zones = useIM(() => {
    // Include zones defined in the warehouse layout + any "orphan" zones that exist
    // in locations but aren't in the layout (so they still appear on the floor plan)
    const cfg = cwh.zones.map(z => z.zone);
    const extra = [...new Set(state.locations.filter(l => l.wh === cwh.id && !cfg.includes(l.zone)).map(l => l.zone))]
      .sort()
      .map(zn => {
        const loc = state.locations.find(l => l.wh === cwh.id && l.zone === zn);
        return { zone: zn, name: loc?.zoneName || zn, racks: 1, shelves: 1 };
      });
    return [...cwh.zones, ...extra].map(zCfg => {
      const locs = state.locations.filter(l => l.wh === cwh.id && l.zone === zCfg.zone);
      const stocks = state.stock.filter(s => locs.some(l => l.id === s.locId));
      return {
        ...zCfg,
        locs,
        totalQty: stocks.reduce((a, b) => a + b.qty, 0),
        skuCount: new Set(stocks.map(s => s.sku)).size,
        capacity: locs.length * 200,
      };
    });
  }, [state, cwh.id]);

  const racksOfZone = useIM(() => {
    const zone = state.locations.filter(l => l.wh === cwh.id && l.zone === selectedZone);
    const map = {};
    zone.forEach(l => {
      if (!map[l.rack]) map[l.rack] = { rack: l.rack, shelves: [] };
      const stockQty = state.stock.filter(s => s.locId === l.id).reduce((a,b)=>a+b.qty,0);
      const skus = new Set(state.stock.filter(s => s.locId === l.id).map(s => s.sku));
      map[l.rack].shelves.push({ ...l, qty: stockQty, skus: skus.size });
    });
    return Object.values(map).sort((a,b)=>a.rack.localeCompare(b.rack));
  }, [state, selectedZone, cwh.id]);

  const totalBins = state.locations.length;

  const addLocation = () => {
    const zoneU = String(form.zone || '').trim().toUpperCase();
    if (!zoneU || !form.rack || !form.shelf) { toast.error('กรอกข้อมูลให้ครบ'); return; }
    const id = `${cwh.id}-${zoneU}-R${String(form.rack).padStart(2, '0')}-S${form.shelf}`;
    if (state.locations.find(l => l.id === id)) { toast.error('Location ซ้ำ', id); return; }
    const zoneInfo = cwh.zones.find(z => z.zone === zoneU);
    const isNewZone = !zoneInfo;
    setState(s => ({
      ...s,
      // Auto-register a brand-new zone into the warehouse layout so it shows on the floor plan
      warehouses: isNewZone
        ? s.warehouses.map(w => w.id === cwh.id ? { ...w, zones: [...w.zones, { zone: zoneU, name: zoneU, racks: 1, shelves: 1 }] } : w)
        : s.warehouses,
      locations: [...s.locations, {
        id, wh: cwh.id, whName: cwh.name,
        zone: zoneU, zoneName: zoneInfo?.name || zoneU,
        rack: `R${String(form.rack).padStart(2,'0')}`, shelf: `S${form.shelf}`,
      }],
    }));
    toast.success(isNewZone ? `เพิ่ม Zone ${zoneU} ใหม่ + Location` : 'เพิ่ม Location ใหม่', `${cwh.name} · ${id}`);
    fireConfetti();
    setSelectedZone(zoneU);
    setAddOpen(false);
  };

  const addWarehouse = () => {
    if (!whForm.id || !whForm.name || !whForm.city) { toast.error('กรอกข้อมูลให้ครบ'); return; }
    const exists = state.warehouses.find(w => w.id === whForm.id.toUpperCase());
    if (exists) { toast.error('รหัสคลังซ้ำ', whForm.id); return; }
    const newWh = {
      id: whForm.id.toUpperCase(), code: whForm.id.toUpperCase(),
      name: whForm.name, name_th: whForm.name,
      city: whForm.city.toUpperCase(), address: whForm.address,
      manager: '—', size: '—', area_sqm: 0, established: String(new Date().getFullYear()),
      timezone: 'GMT+7', kind: whForm.kind,
      zones: [
        { zone: 'A', name: 'Receiving',  x: 4,  y: 6,  w: 30, h: 40, racks: 4, shelves: 3 },
        { zone: 'B', name: 'Storage',    x: 36, y: 6,  w: 60, h: 40, racks: 6, shelves: 4 },
        { zone: 'C', name: 'Shipping',   x: 4,  y: 50, w: 92, h: 22, racks: 4, shelves: 3 },
      ],
      dock: { side: 'bottom', start: 40, end: 60, label: 'LOADING DOCK' },
    };
    // Generate seed locations for new warehouse
    const newLocs = [];
    newWh.zones.forEach(z => {
      for (let r = 1; r <= z.racks; r++) {
        for (let s2 = 1; s2 <= z.shelves; s2++) {
          newLocs.push({
            id: `${newWh.id}-${z.zone}-R${String(r).padStart(2, '0')}-S${s2}`,
            wh: newWh.id, whName: newWh.name,
            zone: z.zone, zoneName: z.name,
            rack: `R${String(r).padStart(2, '0')}`, shelf: `S${s2}`,
          });
        }
      }
    });
    setState(s => ({
      ...s,
      warehouses: [...s.warehouses, newWh],
      locations: [...s.locations, ...newLocs],
      currentWh: newWh.id,
    }));
    toast.success('เพิ่ม Warehouse ใหม่', `${newWh.id} · ${newWh.name}`);
    fireConfetti();
    setAddWhOpen(false);
    setWhForm({ id: '', name: '', city: '', address: '', kind: 'คลังเจ้านาง' });
  };

  return (
    <div className="page-enter">
      <div className="page-header">
        <div>
          <h2 className="page-title">Locations & Warehouse Map <span className="muted mono" style={{fontSize:14, marginLeft:8}}>// MULTI-WH</span></h2>
          <div className="page-subtitle">{state.warehouses.length} warehouses · {totalBins} bins · viewing <span style={{color:'var(--accent)'}}>{cwh.id} {cwh.name}</span></div>
        </div>
        <div className="row">
          <button className="btn btn-ghost" onClick={() => {
            const rows = [...state.locations]
              .sort((a, b) => String(a.wh || '').localeCompare(String(b.wh || '')) || cmpLoc(a, b))
              .map(l => {
                const w = state.warehouses.find(x => x.id === l.wh) || {};
                const qty = state.stock.filter(s => s.locId === l.id).reduce((a, b) => a + b.qty, 0);
                return [l.wh, w.name || '', w.kind || '', l.zone, l.zoneName || '', l.rack, l.shelf, l.id, qty];
              });
            downloadCSV('warehouse-layout.csv', ['Warehouse ID', 'Warehouse', 'ประเภท', 'Zone', 'Zone Name', 'Rack', 'Shelf', 'Location ID', 'คงเหลือ'], rows);
          }}><Ic name="export" size={14}/>Export Layout</button>
          <button className="btn btn-ghost" onClick={() => setAddWhOpen(true)}><Ic name="plus" size={14}/>เพิ่ม Warehouse</button>
          <button className="btn btn-primary" onClick={() => setAddOpen(true)}><Ic name="plus" size={14}/>เพิ่ม Location</button>
        </div>
      </div>

      {/* ===== Warehouse switcher strip ===== */}
      <div className="wh-strip">
        {allWhStats.map(wh => {
          const active = wh.id === cwh.id;
          return (
            <div key={wh.id}
              className={`wh-card ${active ? 'active' : ''}`}
              onClick={() => store.setCurrentWh(wh.id)}>
              <button className="wh-card-edit" data-tip="แก้ไข Warehouse"
                onClick={(e) => { e.stopPropagation(); setEditWh(wh); }}>
                <Ic name="edit" size={12}/>
              </button>
              <div className="wh-card-head">
                <div className="wh-card-mark">{wh.id.split('-')[1] || wh.id.slice(-2)}</div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div className="row" style={{ justifyContent: 'space-between' }}>
                    <span className="mono" style={{ fontSize: 11, color: active ? 'var(--accent)' : 'var(--text-muted)' }}>{wh.id}</span>
                    <span className={`badge ${active ? 'ok' : 'neutral'}`}>{active ? 'VIEWING' : wh.kind.toUpperCase()}</span>
                  </div>
                  <div style={{ fontSize: 14, fontWeight: 600, marginTop: 2, color: 'var(--text-primary)' }}>{wh.name}</div>
                  <div className="mono" style={{ fontSize: 10.5, color: 'var(--text-muted)' }}>{wh.city} · {wh.size}</div>
                </div>
              </div>
              <div className="wh-card-stats">
                <div><div className="lbl">BINS</div><div className="val mono">{wh.locCount}</div></div>
                <div><div className="lbl">SKUS</div><div className="val mono">{wh.skuCount}</div></div>
                <div><div className="lbl">QTY</div><div className="val mono">{wh.totalQty.toLocaleString()}</div></div>
              </div>
              <div className="wh-card-bar">
                <div className="wh-card-bar-fill" style={{ width: `${wh.util}%` }}/>
                <span className="mono">{Math.round(wh.util)}% util</span>
              </div>
            </div>
          );
        })}
      </div>

      <div className="grid-2" style={{ gridTemplateColumns: '1.4fr 1fr', gap: 18, alignItems: 'flex-start' }}>
        {/* Map */}
        <div className="card tech">
          <div className="card-head">
            <div>
              <div className="card-title">Floor Plan · {cwh.name}</div>
              <div className="card-sub">{cwh.id} · {cwh.city} · CLICK_ZONE · VIEW_{selectedZone}</div>
            </div>
            <div className="row" style={{ gap: 6 }}>
              <span className="mono" style={{ fontSize: 10, color: 'var(--text-muted)' }}>FILL:</span>
              <span className="dot-ind" style={{ background: 'var(--success)'}}/><span className="mono" style={{ fontSize: 10 }}>ต่ำ</span>
              <span className="dot-ind" style={{ background: 'var(--accent)'}}/>
              <span className="dot-ind" style={{ background: 'var(--info)'}}/>
              <span className="dot-ind" style={{ background: 'var(--purple)'}}/>
              <span className="dot-ind" style={{ background: 'var(--warning)'}}/><span className="mono" style={{ fontSize: 10 }}>เต็ม</span>
            </div>
          </div>

          <div className="wh-map" key={cwh.id} style={{ minHeight: 52 + Math.ceil(zones.length / 2) * 152 + 46 }}>
            {/* Compass + dock */}
            <div style={{ position: 'absolute', top: 12, left: 12, fontSize: 10, color: 'var(--accent)', fontFamily: 'var(--font-mono)' }}>
              ▲ N · {cwh.size} · {cwh.area_sqm.toLocaleString()} ㎡
            </div>
            <div style={{ position: 'absolute', top: 12, right: 12, fontSize: 10, color: 'var(--text-muted)', fontFamily: 'var(--font-mono)' }}>
              {cwh.id} / {cwh.kind.toUpperCase()}
            </div>

            {/* Dock */}
            {cwh.dock && cwh.dock.side === 'bottom' && (
              <>
                <div style={{ position: 'absolute', bottom: 4, left: `${cwh.dock.start}%`, right: `${100-cwh.dock.end}%`, height: 16, background: 'repeating-linear-gradient(45deg, var(--warning) 0 4px, transparent 4px 10px)', opacity: 0.5 }}/>
                <div style={{ position: 'absolute', bottom: 18, left: `${cwh.dock.start + 2}%`, fontSize: 10, color: 'var(--warning)', fontFamily: 'var(--font-mono)' }}>
                  ▼ {cwh.dock.label}
                </div>
              </>
            )}
            {cwh.dock && cwh.dock.side === 'right' && (
              <>
                <div style={{ position: 'absolute', right: 4, top: `${cwh.dock.start}%`, bottom: `${100-cwh.dock.end}%`, width: 16, background: 'repeating-linear-gradient(45deg, var(--warning) 0 4px, transparent 4px 10px)', opacity: 0.5 }}/>
                <div style={{ position: 'absolute', right: 24, top: `${cwh.dock.start + 4}%`, fontSize: 10, color: 'var(--warning)', fontFamily: 'var(--font-mono)', writingMode: 'vertical-rl' }}>
                  ► {cwh.dock.label}
                </div>
              </>
            )}

            {zones.map((z, i) => {
              const util = Math.min(100, (z.totalQty / Math.max(1, z.capacity)) * 100);
              // Auto grid layout (2 columns, flows down) — scales to any number of zones
              const col = i % 2, row = Math.floor(i / 2);
              return (
                <div key={z.zone}
                  className={`wh-zone ${selectedZone === z.zone ? 'selected' : ''}`}
                  style={{ left: `${col * 50 + 1.5}%`, top: `${52 + row * 152}px`, width: '47%', height: '138px' }}
                  onClick={() => { setSelectedZone(z.zone); setZoneNameEdit(null); }}>
                  <div className="row" style={{ justifyContent: 'space-between' }}>
                    <span className="wh-zone-label">ZONE-{z.zone}</span>
                    <span className="mono" style={{ fontSize: 9.5, color: 'var(--text-muted)' }}>{z.locs.length} bins</span>
                  </div>
                  <div style={{ fontSize: 10.5, color: 'var(--text-secondary)' }}>{z.name}</div>
                  <div className="wh-racks" style={{ flex: 1 }}>
                    {z.locs.slice(0, 30).map(l => {
                      const q = state.stock.filter(s => s.locId === l.id).reduce((a,b)=>a+b.qty,0);
                      const lvl = q === 0 ? 'lvl0' : q < 50 ? 'lvl1' : q < 120 ? 'lvl2' : q < 200 ? 'lvl3' : q < 280 ? 'lvl4' : 'lvl5';
                      return <div key={l.id} className={`wh-rack ${lvl}`} data-tip={`${l.id} · ${q}`}/>;
                    })}
                  </div>
                  <div className="row" style={{ justifyContent: 'space-between', borderTop: '1px dashed var(--border)', paddingTop: 6 }}>
                    <span className="mono" style={{ fontSize: 10, color: 'var(--accent)' }}>{z.totalQty.toLocaleString()} u</span>
                    <span className="mono" style={{ fontSize: 10, color: 'var(--text-muted)' }}>{util.toFixed(0)}%</span>
                  </div>
                </div>
              );
            })}
          </div>

          {/* warehouse meta footer */}
          <div className="wh-map-foot">
            <div><span className="lbl">MANAGER</span><span className="val">{cwh.manager}</span></div>
            <div><span className="lbl">ADDRESS</span><span className="val">{cwh.address}</span></div>
            <div><span className="lbl">EST</span><span className="val mono">{cwh.established}</span></div>
            <div><span className="lbl">TZ</span><span className="val mono">{cwh.timezone}</span></div>
          </div>
        </div>

        {/* Zone detail */}
        <div className="card tech" style={{ position: 'sticky', top: 0 }}>
          {(() => {
            const z = zones.find(z => z.zone === selectedZone);
            if (!z) return null;
            return (
              <>
                <div className="card-head">
                  <div style={{ minWidth: 0, flex: 1 }}>
                    <span className="mono" style={{ fontSize: 11, color: 'var(--accent)' }}>{cwh.id} / ZONE-{z.zone}</span>
                    {zoneNameEdit !== null ? (
                      <div className="row" style={{ gap: 6, marginTop: 2 }}>
                        <input className="input" autoFocus value={zoneNameEdit}
                          onChange={e => setZoneNameEdit(e.target.value)}
                          onKeyDown={e => {
                            if (e.key === 'Enter') { store.renameZone(cwh.id, z.zone, zoneNameEdit); toast.success('แก้ชื่อ Zone', zoneNameEdit); setZoneNameEdit(null); }
                            if (e.key === 'Escape') setZoneNameEdit(null);
                          }}
                          style={{ fontSize: 14, padding: '4px 8px', maxWidth: 200 }}
                          placeholder="ชื่อ Zone (เช่น Receiving)"/>
                        <button className="icon-btn" data-tip="บันทึก"
                          onClick={() => { store.renameZone(cwh.id, z.zone, zoneNameEdit); toast.success('แก้ชื่อ Zone', zoneNameEdit); setZoneNameEdit(null); }}><Ic name="check" size={14}/></button>
                        <button className="icon-btn" data-tip="ยกเลิก" onClick={() => setZoneNameEdit(null)}><Ic name="x" size={14}/></button>
                      </div>
                    ) : (
                      <div className="row" style={{ gap: 6 }}>
                        <div className="card-title">{z.name}</div>
                        <button className="icon-btn" data-tip="แก้ชื่อ Zone" onClick={() => setZoneNameEdit(z.name)}><Ic name="edit" size={12}/></button>
                      </div>
                    )}
                  </div>
                  <span className="badge info">{z.locs.length} BINS</span>
                </div>

                <div className="grid-2" style={{ marginBottom: 16 }}>
                  <MiniKPI label="Qty" value={z.totalQty} color="var(--accent)"/>
                  <MiniKPI label="SKUs" value={z.skuCount} color="var(--purple)"/>
                </div>

                <div className="card-title" style={{ marginBottom: 10 }}>Racks & Shelves</div>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 6, maxHeight: 380, overflowY: 'auto' }}>
                  {racksOfZone.map(r => (
                    <div key={r.rack} style={{ border: '1px solid var(--border)', borderRadius: 8, padding: 8, background: 'var(--bg-base)' }}>
                      <div className="row" style={{ justifyContent: 'space-between', marginBottom: 6 }}>
                        <span className="mono" style={{ fontSize: 11, color: 'var(--accent)' }}>{r.rack}</span>
                        <span className="mono" style={{ fontSize: 10.5, color: 'var(--text-muted)' }}>{r.shelves.reduce((a,b)=>a+b.qty,0)} u</span>
                      </div>
                      <div className="row" style={{ gap: 4, flexWrap: 'wrap' }}>
                        {r.shelves.map(s => (
                          <div key={s.id} className="shelf-chip mono" data-tip={`${s.id} · ${s.qty} units · ${s.skus} SKUs · คลิกเพื่อแก้ไข`}
                            onClick={() => setEditLoc(s)}
                            style={{ flex: '1 1 60px', minWidth: 60, padding: '6px 8px', borderRadius: 4, fontSize: 10.5,
                              background: s.qty === 0 ? 'var(--bg-card-2)' : s.qty < 80 ? 'var(--success-soft)' : s.qty < 180 ? 'var(--accent-soft)' : 'var(--info-soft)',
                              border: `1px solid ${s.qty === 0 ? 'var(--border)' : s.qty < 80 ? 'rgba(16,210,154,0.25)' : s.qty < 180 ? 'rgba(34,211,238,0.25)' : 'rgba(77,139,255,0.25)'}`,
                              color: s.qty === 0 ? 'var(--text-muted)' : 'var(--text-primary)',
                              textAlign: 'center', cursor: 'pointer',
                            }}>
                            {s.shelf}<br/>
                            <span style={{ fontSize: 9, color: 'var(--text-muted)' }}>{s.qty}</span>
                          </div>
                        ))}
                      </div>
                    </div>
                  ))}
                </div>
              </>
            );
          })()}
        </div>
      </div>

      <Modal open={addOpen} onClose={() => setAddOpen(false)} title={`เพิ่ม Location ใหม่ใน ${cwh.id} ${cwh.name}`}
        footer={(
          <>
            <button className="btn btn-ghost" onClick={() => setAddOpen(false)}>ยกเลิก</button>
            <button className="btn btn-primary" onClick={addLocation}><Ic name="check" size={14}/>เพิ่ม Location</button>
          </>
        )}>
        <div className="grid-3">
          <div className="field"><label>Zone</label>
            <input className="input mono" value={form.zone} placeholder="A" maxLength={4}
              onChange={e => setForm({...form, zone: e.target.value.toUpperCase()})}/>
          </div>
          <div className="field"><label>Rack #</label><input className="input mono" value={form.rack} onChange={e => setForm({...form, rack: e.target.value})}/></div>
          <div className="field"><label>Shelf #</label><input className="input mono" value={form.shelf} onChange={e => setForm({...form, shelf: e.target.value})}/></div>
        </div>
        <div className="mono" style={{ fontSize: 10.5, color: 'var(--text-muted)', marginTop: 8 }}>
          Zones ที่มีในคลังนี้: {cwh.zones.map(z => `${z.zone} (${z.name})`).join(' · ')}
        </div>
        <div className="card" style={{ marginTop: 14, padding: 14, background: 'var(--bg-base)' }}>
          <div className="mono" style={{ fontSize: 10.5, color: 'var(--text-muted)' }}>PREVIEW ID</div>
          <div className="mono" style={{ fontSize: 18, color: 'var(--accent)', marginTop: 4 }}>{cwh.id}-{form.zone || '?'}-R{String(form.rack||'').padStart(2,'0')}-S{form.shelf||'?'}</div>
        </div>
      </Modal>

      {/* ===== Edit Warehouse modal ===== */}
      <EditWarehouseModal wh={editWh} onClose={() => setEditWh(null)}/>

      {/* ===== Edit Location modal ===== */}
      <EditLocationModal loc={editLoc} onClose={() => setEditLoc(null)}/>

      <Modal open={addWhOpen} onClose={() => setAddWhOpen(false)} title="เพิ่ม Warehouse ใหม่" width={620}
        footer={(
          <>
            <button className="btn btn-ghost" onClick={() => setAddWhOpen(false)}>ยกเลิก</button>
            <button className="btn btn-primary" onClick={addWarehouse}><Ic name="check" size={14}/>สร้าง Warehouse</button>
          </>
        )}>
        <div className="grid-2">
          <div className="field"><label>Warehouse ID</label><input className="input mono" value={whForm.id} placeholder="WH-04" onChange={e => setWhForm({...whForm, id: e.target.value})}/></div>
          <div className="field"><label>ประเภท</label>
            <select className="select" value={whForm.kind} onChange={e => setWhForm({...whForm, kind: e.target.value})}>
              <option>คลังเจ้านาง</option><option>คลังเช่า</option><option>คลังฝาก</option>
            </select>
          </div>
          <div className="field" style={{gridColumn:'1 / 3'}}><label>ชื่อคลัง</label><input className="input" value={whForm.name} placeholder="Phuket Hub" onChange={e => setWhForm({...whForm, name: e.target.value})}/></div>
          <div className="field"><label>เมือง / City</label><input className="input" value={whForm.city} placeholder="PHUKET" onChange={e => setWhForm({...whForm, city: e.target.value})}/></div>
          <div className="field"><label>ที่อยู่</label><input className="input" value={whForm.address} placeholder="เชิงทะเล, ภูเก็ต" onChange={e => setWhForm({...whForm, address: e.target.value})}/></div>
        </div>
        <div className="card" style={{ marginTop: 14, padding: 14, background: 'var(--bg-base)' }}>
          <div className="mono" style={{ fontSize: 10.5, color: 'var(--text-muted)' }}>DEFAULT LAYOUT</div>
          <div className="mono" style={{ fontSize: 12, color: 'var(--text-secondary)', marginTop: 4 }}>3 zones (A: Receiving · B: Storage · C: Shipping) · ~42 bins · พร้อมแก้ไขภายหลัง</div>
        </div>
      </Modal>
    </div>
  );
}

Object.assign(window, { PageItems, PageItemDetail, PageLocations, MovementBadge });

// ========= Edit Warehouse Modal =========
function EditWarehouseModal({ wh, onClose }) {
  const store = useStore();
  const toast = useToast();
  const [form, setForm] = useIS(null);
  React.useEffect(() => {
    if (wh) setForm({ id: wh.id, name: wh.name, city: wh.city, address: wh.address || '', manager: wh.manager || '', kind: wh.kind || '', size: wh.size || '' });
  }, [wh]);
  if (!wh || !form) return null;

  const check = store.canDeleteWarehouse(wh.id);

  const save = () => {
    if (!form.name.trim()) { toast.error('กรอกชื่อคลัง'); return; }
    // Only treat as a rename if the user actually edited the ID field
    const idChanged = String(form.id) !== wh.id;
    const newId = idChanged ? String(form.id).trim().toUpperCase().replace(/\s+/g, '-') : wh.id;
    if (!newId) { toast.error('กรอกรหัสคลัง (Warehouse ID)'); return; }
    if (idChanged && newId !== wh.id && store.state.warehouses.find(w => w.id === newId)) {
      toast.error('รหัสคลังซ้ำ', newId); return;
    }
    const { id, ...fields } = form;
    if (idChanged && newId !== wh.id) store.renameWarehouse(wh.id, newId);
    store.updateWarehouse(newId, { ...fields, city: form.city.toUpperCase() });
    toast.success('บันทึก Warehouse', idChanged && newId !== wh.id ? `${wh.id} → ${newId}` : form.name);
    onClose();
  };

  const del = () => {
    if (!check.ok) { toast.error('ลบไม่ได้', check.reason); return; }
    if (!confirm(`ลบ Warehouse ${wh.id} (${wh.name}) ?\n\nจะลบ ${check.locCount} locations ด้วย · ทำไม่ได้คืน`)) return;
    store.deleteWarehouse(wh.id);
    toast.success('ลบ Warehouse แล้ว', `${wh.id} · ${wh.name}`);
    onClose();
  };

  return (
    <Modal open={!!wh} onClose={onClose} width={620} title={`แก้ไข Warehouse · ${wh.id}`}
      footer={(
        <>
          <button className="btn btn-danger" onClick={del} disabled={!check.ok}
            data-tip={!check.ok ? check.reason : undefined}>
            <Ic name="trash" size={14}/>ลบ Warehouse
          </button>
          <span className="spacer"/>
          <button className="btn btn-ghost" onClick={onClose}>ยกเลิก</button>
          <button className="btn btn-primary" onClick={save}><Ic name="check" size={14}/>บันทึก</button>
        </>
      )}>
      <div className="row" style={{ marginBottom: 14, padding: 10, background: 'var(--bg-base)', borderRadius: 8, gap: 12 }}>
        <div className="wh-card-mark" style={{ width: 40, height: 40, flex: '0 0 40px' }}>{String(form.id || wh.id).split('-')[1] || String(form.id || wh.id).slice(-2)}</div>
        <div style={{ flex: 1 }}>
          <label className="mono" style={{ fontSize: 9.5, color: 'var(--text-dim)', letterSpacing: '0.1em' }}>WAREHOUSE_ID</label>
          <input className="input mono" style={{ fontSize: 12, padding: '6px 8px', marginTop: 2 }}
            value={form.id} onChange={e => setForm({ ...form, id: e.target.value })}/>
          <div className="mono" style={{ fontSize: 10, color: 'var(--warning)', marginTop: 3 }}>
            {form.id !== wh.id ? '⚠ เปลี่ยน ID → location ทั้งหมดจะถูก rename ตาม' : 'เปลี่ยนได้ · location จะ rename ตาม'}
          </div>
        </div>
        <div style={{ textAlign: 'right' }}>
          <div className="mono" style={{ fontSize: 10.5, color: 'var(--text-muted)' }}>LOCATIONS</div>
          <div className="mono" style={{ fontSize: 16, color: 'var(--accent)', fontWeight: 700 }}>{check.locCount || 0}</div>
        </div>
      </div>
      <div className="grid-2">
        <div className="field" style={{ gridColumn: '1 / 3' }}>
          <label>ชื่อคลัง</label>
          <input className="input" value={form.name} onChange={e => setForm({...form, name: e.target.value})}/>
        </div>
        <div className="field"><label>เมือง / City</label><input className="input" value={form.city} onChange={e => setForm({...form, city: e.target.value})}/></div>
        <div className="field"><label>ประเภท</label><input className="input" value={form.kind} onChange={e => setForm({...form, kind: e.target.value})}/></div>
        <div className="field" style={{ gridColumn: '1 / 3' }}><label>ที่อยู่</label><input className="input" value={form.address} onChange={e => setForm({...form, address: e.target.value})}/></div>
        <div className="field"><label>ผู้จัดการ</label><input className="input" value={form.manager} onChange={e => setForm({...form, manager: e.target.value})}/></div>
        <div className="field"><label>ขนาดพื้นที่</label><input className="input mono" value={form.size} onChange={e => setForm({...form, size: e.target.value})}/></div>
      </div>

      {!check.ok && (
        <div className="row" style={{ marginTop: 14, padding: '8px 12px', background: 'var(--warning-soft)', borderRadius: 8, border: '1px solid rgba(245,179,42,0.25)', fontSize: 12, color: 'var(--warning)' }}>
          <Ic name="alert" size={14}/>
          <span>ลบ Warehouse ไม่ได้ · {check.reason} · ต้องโอน/จ่ายออกสต็อกทั้งหมดก่อน</span>
        </div>
      )}
    </Modal>
  );
}

// ========= Edit / Delete Location Modal =========
function EditLocationModal({ loc, onClose }) {
  const store = useStore();
  const toast = useToast();
  const [form, setForm] = useIS(null);
  React.useEffect(() => {
    if (loc) setForm({ zone: loc.zone, rack: loc.rack.replace(/^R/, ''), shelf: loc.shelf.replace(/^S/, ''), zoneName: loc.zoneName || '' });
  }, [loc]);
  if (!loc || !form) return null;

  const totalQty = store.state.stock.filter(x => x.locId === loc.id).reduce((a,b) => a + b.qty, 0);
  const canDelete = totalQty === 0;

  const newId = `${loc.wh}-${form.zone}-R${String(form.rack).padStart(2,'0')}-S${form.shelf}`;
  const changed = newId !== loc.id;
  const conflict = changed && store.state.locations.find(l => l.id === newId);

  const save = () => {
    if (!form.zone || !form.rack || !form.shelf) { toast.error('กรอกข้อมูลให้ครบ'); return; }
    if (conflict) { toast.error('Location ใหม่ซ้ำ', newId); return; }
    store.updateLocation(loc.id, {
      zone: form.zone.toUpperCase(),
      rack: `R${String(form.rack).padStart(2, '0')}`,
      shelf: `S${form.shelf}`,
      zoneName: form.zoneName,
    });
    toast.success('บันทึก Location', changed ? `${loc.id} → ${newId}` : loc.id);
    onClose();
  };

  const del = () => {
    if (!canDelete) { toast.error('ลบไม่ได้', `ยังมีสต็อก ${totalQty} units อยู่`); return; }
    if (!confirm(`ลบ Location ${loc.id} ?`)) return;
    store.deleteLocation(loc.id);
    toast.success('ลบ Location แล้ว', loc.id);
    onClose();
  };

  return (
    <Modal open={!!loc} onClose={onClose} width={560} title={`แก้ไข Location · ${loc.id}`}
      footer={(
        <>
          <button className="btn btn-danger" onClick={del} disabled={!canDelete}
            data-tip={!canDelete ? `ยังมีสต็อก ${totalQty} units อยู่ ลบไม่ได้` : undefined}>
            <Ic name="trash" size={14}/>ลบ Location
          </button>
          <span className="spacer"/>
          <button className="btn btn-ghost" onClick={onClose}>ยกเลิก</button>
          <button className="btn btn-primary" onClick={save} disabled={!!conflict}>
            <Ic name="check" size={14}/>บันทึก
          </button>
        </>
      )}>
      <div className="row" style={{ marginBottom: 14, padding: 10, background: 'var(--bg-base)', borderRadius: 8, justifyContent: 'space-between' }}>
        <div>
          <div className="mono" style={{ fontSize: 11, color: 'var(--text-muted)' }}>WAREHOUSE</div>
          <div style={{ fontSize: 13, fontWeight: 600 }}>{loc.whName || loc.wh}</div>
        </div>
        <div style={{ textAlign: 'right' }}>
          <div className="mono" style={{ fontSize: 11, color: 'var(--text-muted)' }}>STOCK ที่ Location นี้</div>
          <div className="mono" style={{ fontSize: 18, color: canDelete ? 'var(--success)' : 'var(--warning)', fontWeight: 700 }}>
            {totalQty.toLocaleString()} <span style={{ fontSize: 11 }}>units</span>
          </div>
        </div>
      </div>

      <div className="grid-3">
        <div className="field"><label>Zone</label>
          <input className="input mono" value={form.zone} maxLength={4}
            onChange={e => setForm({...form, zone: e.target.value.toUpperCase()})}/>
        </div>
        <div className="field"><label>Rack #</label>
          <input className="input mono" value={form.rack} onChange={e => setForm({...form, rack: e.target.value})}/>
        </div>
        <div className="field"><label>Shelf #</label>
          <input className="input mono" value={form.shelf} onChange={e => setForm({...form, shelf: e.target.value})}/>
        </div>
        <div className="field" style={{ gridColumn: '1 / 4' }}>
          <label>Zone Name (label)</label>
          <input className="input" value={form.zoneName} onChange={e => setForm({...form, zoneName: e.target.value})} placeholder="Receiving Zone / Fast-Moving / ..."/>
        </div>
      </div>

      <div className="card" style={{ marginTop: 14, padding: 14, background: 'var(--bg-base)' }}>
        <div className="row" style={{ justifyContent: 'space-between' }}>
          <div>
            <div className="mono" style={{ fontSize: 10.5, color: 'var(--text-muted)' }}>NEW ID</div>
            <div className="mono" style={{ fontSize: 18, color: conflict ? 'var(--danger)' : changed ? 'var(--accent)' : 'var(--text-secondary)', marginTop: 4 }}>{newId}</div>
          </div>
          {conflict && <span className="badge crit">ซ้ำ</span>}
          {!conflict && changed && <span className="badge info">จะ rename + ย้าย stock ref</span>}
          {!changed && <span className="badge neutral">ไม่เปลี่ยน</span>}
        </div>
      </div>

      {!canDelete && (
        <div className="row" style={{ marginTop: 10, padding: '8px 12px', background: 'var(--warning-soft)', borderRadius: 8, border: '1px solid rgba(245,179,42,0.25)', fontSize: 12, color: 'var(--warning)' }}>
          <Ic name="alert" size={14}/>
          <span>ยังมีสต็อกอยู่ที่ Location นี้ {totalQty} units · ต้องโอนหรือจ่ายออกก่อนจึงจะลบได้</span>
        </div>
      )}
    </Modal>
  );
}

Object.assign(window, { EditWarehouseModal, EditLocationModal });
