// crm-orderform.jsx — Order Form Generator

// ── BILLING TYPE OPTIONS ──────────────────────────────────
const BILLING_TYPES = ['One Time', 'Monthly', 'Quarterly', 'Annually', 'Other'];

// ── HELPERS ───────────────────────────────────────────────
const fmt$ = v => '$' + (parseFloat(v) || 0).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
const pct  = v => parseFloat(v) || 0;

function lineExt(line) {
  return (parseFloat(line.quantity) || 0) * (parseFloat(line.unitPrice) || 0);
}

function calcTotals(lines, sh, taxRate, isTaxable) {
  const recurring = lines.filter(l => l.billingType && l.billingType !== 'One Time' && l.billingType !== 'Other');
  const oneTime   = lines.filter(l => !l.billingType || l.billingType === 'One Time' || l.billingType === 'Other');
  const firstMonth  = recurring.reduce((s, l) => s + lineExt(l), 0);
  const lastMonth   = firstMonth;
  const oneTimeFees = oneTime.reduce((s, l) => s + lineExt(l), 0);
  const shNum       = parseFloat(sh) || 0;
  // Tax applies to first month, last month, one-time fees, AND shipping & handling
  // (taxRate is stored as a percentage — e.g. 8.875 — so divide by 100).
  const taxableBase = firstMonth + lastMonth + oneTimeFees + shNum;
  const tax         = isTaxable ? taxableBase * ((parseFloat(taxRate) || 0) / 100) : 0;
  const deposit     = firstMonth + lastMonth + oneTimeFees + shNum + tax;
  return { firstMonth, lastMonth, oneTimeFees, sh: shNum, tax, deposit };
}

// ══════════════════════════════════════════════════════════
// ORDER CATALOG ADMIN TAB
// ══════════════════════════════════════════════════════════
function OrderCatalogAdmin({ showToast }) {
  const [items,    setItems]    = useState([]);
  const [loading,  setLoading]  = useState(true);
  const [showAll,  setShowAll]  = useState(false);
  const [editing,  setEditing]  = useState(null);  // item id or 'new'
  const [saving,   setSaving]   = useState(false);
  const [deleting, setDeleting] = useState(null);

  const blankForm = () => ({ partNumber:'', description:'', billingType:'One Time', unitPrice:'', isActive:true, sortOrder:'0' });
  const [form, setForm] = useState(blankForm());

  const load = async () => {
    setLoading(true);
    try { setItems(await CRM.OrderCatalogAPI.getAll(true)); }
    catch (e) { showToast('Failed to load catalog: ' + e.message, 'error'); }
    finally { setLoading(false); }
  };

  useEffect(() => { load(); }, []);

  const visible = showAll ? items : items.filter(i => i.isActive);

  const startNew = () => { setForm(blankForm()); setEditing('new'); };
  const startEdit = item => {
    setForm({
      partNumber:  item.partNumber  || '',
      description: item.description || '',
      billingType: item.billingType || 'One Time',
      unitPrice:   String(item.unitPrice ?? ''),
      isActive:    item.isActive !== false,
      sortOrder:   String(item.sortOrder ?? 0),
    });
    setEditing(item.id);
  };
  const cancelEdit = () => { setEditing(null); setForm(blankForm()); };

  const doSave = async () => {
    if (!form.description.trim()) return showToast('Description is required.', 'error');
    setSaving(true);
    try {
      if (editing === 'new') {
        const created = await CRM.OrderCatalogAPI.create(form);
        setItems(prev => [...prev, created]);
        showToast('Item added.', 'success');
      } else {
        const updated = await CRM.OrderCatalogAPI.update(editing, form);
        setItems(prev => prev.map(i => i.id === editing ? updated : i));
        showToast('Item saved.', 'success');
      }
      cancelEdit();
    } catch (e) { showToast('Save failed: ' + e.message, 'error'); }
    finally { setSaving(false); }
  };

  const doDelete = async (item) => {
    if (!confirm(`Delete "${item.description}"?`)) return;
    setDeleting(item.id);
    try {
      await CRM.OrderCatalogAPI.delete(item.id);
      setItems(prev => prev.filter(i => i.id !== item.id));
      showToast('Item deleted.', 'success');
    } catch (e) { showToast('Delete failed: ' + e.message, 'error'); }
    finally { setDeleting(null); }
  };

  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  return (
    <div>
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:18 }}>
        <div style={{ display:'flex', alignItems:'center', gap:12 }}>
          <h3 style={{ margin:0, fontSize:16, fontWeight:700, color:'var(--navy)' }}>Order Form Catalog</h3>
          <label style={{ display:'flex', alignItems:'center', gap:5, fontSize:12, color:'var(--g400)', cursor:'pointer', fontWeight:400 }}>
            <input type="checkbox" checked={showAll} onChange={e => setShowAll(e.target.checked)} />
            Show inactive
          </label>
        </div>
        {editing !== 'new' && (
          <button className="btn btn-primary btn-sm" onClick={startNew}>+ Add Item</button>
        )}
      </div>

      {/* New/Edit inline form */}
      {editing && (
        <div className="card card-pad" style={{ marginBottom:20, background:'var(--off)' }}>
          <div style={{ fontWeight:700, fontSize:13, color:'var(--navy)', marginBottom:14 }}>
            {editing === 'new' ? 'New Catalog Item' : 'Edit Item'}
          </div>
          <div className="fg fg-3" style={{ marginBottom:12 }}>
            <div className="field">
              <label>Part Number</label>
              <input value={form.partNumber} onChange={e => set('partNumber', e.target.value)} placeholder="e.g. GT8-DUAL" />
            </div>
            <div className="field" style={{ gridColumn:'span 2' }}>
              <label>Description *</label>
              <input value={form.description} onChange={e => set('description', e.target.value)} placeholder="e.g. GT8 Dual Biometric Time Clock" />
            </div>
          </div>
          <div className="fg fg-4" style={{ marginBottom:12 }}>
            <div className="field">
              <label>Billing Type</label>
              <select value={form.billingType} onChange={e => set('billingType', e.target.value)}>
                {BILLING_TYPES.map(t => <option key={t}>{t}</option>)}
              </select>
            </div>
            <div className="field">
              <label>Unit Price</label>
              <input type="number" step="0.01" min="0" value={form.unitPrice} onChange={e => set('unitPrice', e.target.value)} placeholder="0.00" />
            </div>
            <div className="field">
              <label>Sort Order</label>
              <input type="number" min="0" value={form.sortOrder} onChange={e => set('sortOrder', e.target.value)} placeholder="0" />
            </div>
            <div className="field" style={{ display:'flex', alignItems:'center', gap:8, paddingTop:22 }}>
              <label style={{ display:'flex', alignItems:'center', gap:6, cursor:'pointer', fontWeight:400 }}>
                <input type="checkbox" checked={form.isActive} onChange={e => set('isActive', e.target.checked)} />
                Active
              </label>
            </div>
          </div>
          <div style={{ display:'flex', gap:8, justifyContent:'flex-end' }}>
            <button className="btn btn-ghost btn-sm" onClick={cancelEdit} disabled={saving}>Cancel</button>
            <button className="btn btn-primary btn-sm" onClick={doSave} disabled={saving}>
              {saving ? 'Saving…' : '✓ Save Item'}
            </button>
          </div>
        </div>
      )}

      {loading ? (
        <div className="empty"><div className="empty-icon">⏳</div><div className="empty-text">Loading…</div></div>
      ) : visible.length === 0 ? (
        <div className="empty">
          <div className="empty-icon">📋</div>
          <div className="empty-text">No catalog items yet. Add your first item above.</div>
        </div>
      ) : (
        <div className="card">
          <table className="tbl">
            <thead>
              <tr>
                <th style={{width:80}}>Part #</th>
                <th>Description</th>
                <th style={{width:110}}>Billing Type</th>
                <th style={{width:100, textAlign:'right'}}>Unit Price</th>
                <th style={{width:60, textAlign:'center'}}>Order</th>
                <th style={{width:70, textAlign:'center'}}>Active</th>
                <th style={{width:110}}></th>
              </tr>
            </thead>
            <tbody>
              {visible.map(item => (
                <tr key={item.id} style={{ opacity: item.isActive ? 1 : 0.5 }}>
                  <td style={{ fontFamily:'monospace', fontSize:12, color:'var(--g600)' }}>{item.partNumber || '—'}</td>
                  <td style={{ fontWeight:600, color:'var(--navy)' }}>{item.description}</td>
                  <td><span style={{ fontSize:11, background:'var(--off)', padding:'2px 6px', borderRadius:4, color:'var(--g600)' }}>{item.billingType}</span></td>
                  <td style={{ textAlign:'right', fontFamily:'monospace' }}>{fmt$(item.unitPrice)}</td>
                  <td style={{ textAlign:'center', color:'var(--g400)' }}>{item.sortOrder}</td>
                  <td style={{ textAlign:'center' }}>{item.isActive ? '✅' : '—'}</td>
                  <td>
                    <div style={{ display:'flex', gap:5, justifyContent:'flex-end' }}>
                      <button className="btn btn-ghost btn-xs" onClick={() => startEdit(item)}>✏ Edit</button>
                      <button className="btn btn-xs" disabled={deleting === item.id}
                        style={{ background:'#FEF2F2', color:'#991B1B', border:'1px solid #FECACA' }}
                        onClick={() => doDelete(item)}>
                        {deleting === item.id ? '…' : '🗑'}
                      </button>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
}

// ══════════════════════════════════════════════════════════
// ACCOUNT ORDER FORMS TAB
// ══════════════════════════════════════════════════════════
function AccountOrderFormsTab({ account, user, showToast }) {
  const [orders,  setOrders]  = useState([]);
  const [loading, setLoading] = useState(true);
  const [view,    setView]    = useState(null);  // 'new' | {order form object for preview/reprint}
  const [deleting, setDeleting] = useState(null);

  const load = async () => {
    setLoading(true);
    try { setOrders(await CRM.OrderFormsAPI.listForAccount(account.id)); }
    catch (e) { showToast('Failed to load orders: ' + e.message, 'error'); }
    finally { setLoading(false); }
  };

  useEffect(() => { load(); }, [account.id]);

  const handleSaved = (saved) => {
    setOrders(prev => [saved, ...prev.filter(o => o.id !== saved.id)]);
    setView({ mode:'preview', form: saved });
  };

  const doDelete = async (order) => {
    if (!confirm('Delete this order form? This cannot be undone.')) return;
    setDeleting(order.id);
    try {
      await CRM.OrderFormsAPI.delete(order.id);
      setOrders(prev => prev.filter(o => o.id !== order.id));
      showToast('Order form deleted.', 'success');
    } catch (e) { showToast('Delete failed: ' + e.message, 'error'); }
    finally { setDeleting(null); }
  };

  const openReprint = async (order) => {
    try {
      const full = await CRM.OrderFormsAPI.getOne(order.id);
      setView({ mode:'preview', form: full });
    } catch (e) { showToast('Failed to load order: ' + e.message, 'error'); }
  };

  if (view) {
    if (view.mode === 'new') {
      return (
        <OrderFormIntake
          account={account}
          user={user}
          onSaved={handleSaved}
          onCancel={() => setView(null)}
          showToast={showToast}
        />
      );
    }
    if (view.mode === 'preview') {
      return (
        <OrderFormPreview
          form={view.form}
          account={account}
          onBack={() => setView(null)}
          onNewForm={() => setView({ mode:'new' })}
          showToast={showToast}
        />
      );
    }
  }

  return (
    <div>
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:18 }}>
        <h3 style={{ margin:0, fontSize:15, fontWeight:700, color:'var(--navy)' }}>Order Forms</h3>
        <button className="btn btn-primary btn-sm" onClick={() => setView({ mode:'new' })}>
          + Generate Order Form
        </button>
      </div>

      {loading ? (
        <div className="empty"><div className="empty-icon">⏳</div><div className="empty-text">Loading…</div></div>
      ) : orders.length === 0 ? (
        <div className="empty">
          <div className="empty-icon">📋</div>
          <div className="empty-text">No order forms yet.</div>
        </div>
      ) : (
        <div className="card">
          <table className="tbl">
            <thead>
              <tr>
                <th>Order #</th>
                <th>Order Date</th>
                <th>Cust PO</th>
                <th>Bill To</th>
                <th>Ship To City</th>
                <th style={{textAlign:'center'}}>Lines</th>
                <th>Created By</th>
                <th style={{width:130}}></th>
              </tr>
            </thead>
            <tbody>
              {orders.map(o => (
                <tr key={o.id}>
                  <td style={{ fontWeight:600, color:'var(--navy)' }}>#{toOrderNumber(o.createdAt)}</td>
                  <td>{o.orderDate ? new Date(o.orderDate + 'T00:00:00').toLocaleDateString() : '—'}</td>
                  <td style={{ color:'var(--g400)' }}>{o.custPo || '—'}</td>
                  <td style={{ color:'var(--navy)', fontWeight:500 }}>{o.billToCompany || '—'}</td>
                  <td style={{ color:'var(--g400)' }}>{o.shipToCity || '—'}</td>
                  <td style={{ textAlign:'center', color:'var(--g400)' }}>{o.lineCount}</td>
                  <td style={{ color:'var(--g400)' }}>{o.createdByName || '—'}</td>
                  <td>
                    <div style={{ display:'flex', gap:5, justifyContent:'flex-end' }}>
                      <button className="btn btn-ghost btn-xs" onClick={() => openReprint(o)}>🖨 Print</button>
                      <button className="btn btn-xs" disabled={deleting === o.id}
                        style={{ background:'#FEF2F2', color:'#991B1B', border:'1px solid #FECACA' }}
                        onClick={() => doDelete(o)}>
                        {deleting === o.id ? '…' : '🗑'}
                      </button>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
}

// ── Address parser ─────────────────────────────────────────
// Splits a single free-text address into { address, city, state, zip }.
// Handles the most common US formats stored in the Account.address field:
//   "123 Main St, New York, NY 10001"
//   "123 Main St\nNew York, NY 10001"
//   "123 Main St, New York, NY"
//   "123 Main St"
function parseAccountAddress(raw) {
  if (!raw || !raw.trim()) return { address: '', city: '', state: '', zip: '' };

  // Normalise – collapse \r, split on newline first
  const lines = raw.split(/\r?\n/).map(s => s.trim()).filter(Boolean);

  let street = '';
  let rest   = '';

  if (lines.length >= 2) {
    // Multi-line: first line = street, join remainder as "city, ST ZIP"
    street = lines[0];
    rest   = lines.slice(1).join(', ');
  } else {
    // Single line – left of first comma = street, right = city/state/zip
    const firstComma = raw.indexOf(',');
    if (firstComma === -1) return { address: raw.trim(), city: '', state: '', zip: '' };
    street = raw.slice(0, firstComma).trim();
    rest   = raw.slice(firstComma + 1).trim();
  }

  // Parse rest as "City, ST ZIP" or "City ST ZIP" or "City, ST"
  const m = rest.match(/^(.*?),?\s+\b([A-Za-z]{2})\b\s*(\d[\d-]*)?\s*$/);
  if (m) {
    return {
      address: street,
      city:    m[1].trim(),
      state:   m[2].toUpperCase(),
      zip:     (m[3] || '').trim(),
    };
  }

  // Could not parse city/state – put everything in address
  return { address: raw.trim(), city: '', state: '', zip: '' };
}

// ══════════════════════════════════════════════════════════
// ORDER FORM INTAKE (data entry before printing)
// ══════════════════════════════════════════════════════════
function OrderFormIntake({ account, user, onSaved, onCancel, showToast }) {
  const today = new Date().toISOString().slice(0, 10);

  const [header, setHeader] = useState({
    orderDate:    today,
    custPo:       '',
    salesRepName: user.name || '',
    terms:        (CRM.ORDER_TERMS && CRM.ORDER_TERMS[0]) || 'Net 30 Days',
    leadSource:   '',
  });

  // Prefer the account's structured address fields; fall back to parsing
  // the legacy single-string address for anything not yet migrated.
  const _parsed = (account.address1 || account.city || account.state || account.zip)
    ? { address: [account.address1, account.address2].filter(Boolean).join(', '),
        city: account.city || '', state: account.state || '', zip: account.zip || '' }
    : parseAccountAddress(account.address);
  const [billTo, setBillTo] = useState({
    company: account.companyName || '',
    name:    '',
    address: _parsed.address,
    city:    _parsed.city,
    state:   _parsed.state,
    zip:     _parsed.zip,
    phone:   '',
    email:   '',
  });

  const [shipSame, setShipSame] = useState(true);
  const [shipTo, setShipTo] = useState({ company:'', name:'', address:'', city:'', state:'', zip:'', phone:'', email:'' });

  const [tax, setTax] = useState({ isTaxable: true, taxId:'', jurisdiction:'', taxRate:'', sh:'' });
  const [lines,      setLines]      = useState([newLine()]);
  const [catalog,    setCatalog]    = useState([]);
  const [taxRates,   setTaxRates]   = useState([]);
  const [contacts,   setContacts]   = useState([]);
  const [contactSel, setContactSel] = useState('');   // selected contact id, '' = manual
  const [saving,     setSaving]     = useState(false);

  function newLine() {
    return { _key: Math.random(), catalogItemId:null, partNumber:'', description:'', billingType:'One Time', quantity:'1', unitPrice:'' };
  }

  useEffect(() => {
    CRM.OrderCatalogAPI.getAll().then(setCatalog).catch(() => {});
    CRM.SalesTaxAPI.getAll().then(setTaxRates).catch(() => {});
    CRM.ContactsAPI.getByAccount(account.id).then(list => {
      setContacts(list);
      // Auto-select primary contact if one exists
      const primary = list.find(c => c.isPrimary) || list.find(c => c.primary);
      if (primary) {
        setContactSel(primary.id);
        setBillTo(b => ({ ...b, name: primary.name || '', phone: primary.phone || '', email: primary.email || '' }));
      }
    }).catch(() => {});
  }, []);

  const setH = (k, v) => setHeader(h => ({ ...h, [k]: v }));
  const setB = (k, v) => setBillTo(b => ({ ...b, [k]: v }));
  const setS = (k, v) => setShipTo(s => ({ ...s, [k]: v }));
  const setT = (k, v) => setTax(t => ({ ...t, [k]: v }));

  const setLine = (idx, k, v) => setLines(ls => ls.map((l, i) => i === idx ? { ...l, [k]: v } : l));

  const pickCatalog = (idx, item) => {
    if (!item) { setLine(idx, 'catalogItemId', null); return; }
    setLines(ls => ls.map((l, i) => i === idx ? {
      ...l,
      catalogItemId: item.id,
      partNumber:    item.partNumber  || '',
      description:   item.description || '',
      billingType:   item.billingType || 'One Time',
      unitPrice:     String(item.unitPrice ?? ''),
    } : l));
  };

  const addLine = () => setLines(ls => [...ls, newLine()]);
  const removeLine = idx => setLines(ls => ls.filter((_, i) => i !== idx));

  const totals = calcTotals(
    lines.map(l => ({ ...l, billingType: l.billingType })),
    tax.sh, tax.taxRate, tax.isTaxable
  );

  const doSave = async () => {
    const goodLines = lines.filter(l => l.description.trim() || l.partNumber.trim());
    if (goodLines.length === 0) return showToast('Add at least one line item.', 'error');
    setSaving(true);
    try {
      const payload = {
        orderDate:      header.orderDate || null,
        custPo:         header.custPo    || null,
        terms:          header.terms     || null,
        isTaxable:      tax.isTaxable,
        taxId:          tax.jurisdiction || tax.taxId || null,
        taxRate:        parseFloat(tax.taxRate) || 0,
        shipAndHandle:  parseFloat(tax.sh)  || 0,
        salesRepName:   header.salesRepName || null,
        leadSource:     header.leadSource   || null,
        billToCompany:  billTo.company || null,
        billToName:     billTo.name    || null,
        billToAddress:  billTo.address || null,
        billToCity:     billTo.city    || null,
        billToState:    billTo.state   || null,
        billToZip:      billTo.zip     || null,
        billToPhone:    billTo.phone   || null,
        billToEmail:    billTo.email   || null,
        shipSameAsBill: shipSame,
        shipToCompany:  shipSame ? null : (shipTo.company || null),
        shipToName:     shipSame ? null : (shipTo.name    || null),
        shipToAddress:  shipSame ? null : (shipTo.address || null),
        shipToCity:     shipSame ? null : (shipTo.city    || null),
        shipToState:    shipSame ? null : (shipTo.state   || null),
        shipToZip:      shipSame ? null : (shipTo.zip     || null),
        shipToPhone:    shipSame ? null : (shipTo.phone   || null),
        shipToEmail:    shipSame ? null : (shipTo.email   || null),
        lines: goodLines.map((l, i) => ({
          catalogItemId: l.catalogItemId || null,
          partNumber:    l.partNumber    || null,
          billingType:   l.billingType   || null,
          description:   l.description  || null,
          quantity:      parseFloat(l.quantity)  || 1,
          unitPrice:     parseFloat(l.unitPrice) || 0,
          sortOrder:     i,
        })),
      };
      const saved = await CRM.OrderFormsAPI.save(account.id, payload);
      showToast('Order form saved.', 'success');
      onSaved(saved);
    } catch (e) {
      showToast('Save failed: ' + e.message, 'error');
    } finally {
      setSaving(false);
    }
  };

  const sectionHd = (label) => (
    <div style={{ fontWeight:700, fontSize:12, color:'var(--g400)', textTransform:'uppercase', letterSpacing:'0.05em', marginBottom:8, marginTop:18 }}>
      {label}
    </div>
  );

  // Full-page surface: the account detail panel is only ~820px wide, which made
  // line-item editing cramped — so the intake takes over the whole viewport.
  return (
    <div style={{ position:'fixed', inset:0, zIndex:1100, background:'var(--folio-bg, #F7F7F5)', overflowY:'auto' }}>
    <div style={{ maxWidth:1320, margin:'0 auto', padding:'28px 32px' }}>
      <div style={{ display:'flex', alignItems:'center', gap:12, marginBottom:20 }}>
        <button className="btn btn-ghost btn-sm" onClick={onCancel}>← Back</button>
        <h3 style={{ margin:0, fontSize:15, fontWeight:700, color:'var(--navy)' }}>New Order Form — {account.companyName}</h3>
      </div>

      {/* Header fields */}
      {sectionHd('Order Details')}
      <div className="card card-pad" style={{ marginBottom:16 }}>
        <div className="fg fg-3" style={{ marginBottom:10 }}>
          <div className="field"><label>Order Date</label>
            <input type="date" value={header.orderDate} onChange={e => setH('orderDate', e.target.value)} /></div>
          <div className="field"><label>Cust PO #</label>
            <input value={header.custPo} onChange={e => setH('custPo', e.target.value)} placeholder="Optional" /></div>
          <div className="field"><label>Lead Source</label>
            <input value={header.leadSource} onChange={e => setH('leadSource', e.target.value)} placeholder="Optional" /></div>
        </div>
        <div className="fg fg-2">
          <div className="field"><label>Sales Rep</label>
            <input value={header.salesRepName} onChange={e => setH('salesRepName', e.target.value)} /></div>
          <div className="field"><label>Terms</label>
            <select value={header.terms || ''} onChange={e => setH('terms', e.target.value)}>
              <option value="">— Select —</option>
              {(CRM.ORDER_TERMS || []).map(t => <option key={t} value={t}>{t}</option>)}
            </select>
          </div>
        </div>
      </div>

      {/* Bill To */}
      {sectionHd('Bill To')}
      <div className="card card-pad" style={{ marginBottom:16 }}>
        {/* Contact picker */}
        {contacts.length > 0 && (
          <div className="field" style={{ marginBottom:10 }}>
            <label>Select Contact</label>
            <select value={contactSel} onChange={e => {
              const id = e.target.value;
              setContactSel(id);
              if (!id) return;  // manual — leave fields as-is
              const c = contacts.find(x => x.id === id);
              if (c) setBillTo(b => ({ ...b, name: c.name || '', phone: c.phone || '', email: c.email || '' }));
            }}>
              <option value="">— Enter manually —</option>
              {contacts.map(c => (
                <option key={c.id} value={c.id}>
                  {c.name}{c.title ? ` — ${c.title}` : ''}{c.primary || c.isPrimary ? ' ★' : ''}
                </option>
              ))}
            </select>
          </div>
        )}
        <div className="fg fg-2" style={{ marginBottom:10 }}>
          <div className="field"><label>Company</label>
            <input value={billTo.company} onChange={e => setB('company', e.target.value)} /></div>
          <div className="field"><label>Contact Name</label>
            <input value={billTo.name} onChange={e => { setContactSel(''); setB('name', e.target.value); }} /></div>
        </div>
        <div style={{ display:'flex', gap:8, marginBottom:10 }}>
          <div className="field" style={{ flex:'2 1 0' }}><label>Address</label>
            <input value={billTo.address} onChange={e => setB('address', e.target.value)} /></div>
          <div className="field" style={{ flex:'1.5 1 0' }}><label>City</label>
            <input value={billTo.city} onChange={e => setB('city', e.target.value)} /></div>
          <div className="field" style={{ width:52 }}><label>State</label>
            <input value={billTo.state} onChange={e => setB('state', e.target.value)} maxLength={2} style={{ textTransform:'uppercase' }} /></div>
          <div className="field" style={{ width:80 }}><label>ZIP</label>
            <input value={billTo.zip} onChange={e => setB('zip', e.target.value)} maxLength={5} /></div>
        </div>
        <div style={{ display:'flex', gap:8 }}>
          <div className="field" style={{ width:150 }}><label>Phone</label>
            <input value={billTo.phone} onChange={e => { setContactSel(''); setB('phone', e.target.value); }} /></div>
          <div className="field" style={{ flex:'1 1 0' }}><label>Email</label>
            <input type="email" value={billTo.email} onChange={e => { setContactSel(''); setB('email', e.target.value); }} /></div>
        </div>
      </div>

      {/* Ship To */}
      <label style={{ display:'flex', alignItems:'center', gap:7, fontSize:13, cursor:'pointer', marginBottom:10 }}>
        <input type="checkbox" checked={shipSame} onChange={e => setShipSame(e.target.checked)} />
        Ship to same address as Bill To
      </label>
      {!shipSame && (
        <div className="card card-pad" style={{ marginBottom:16 }}>
          {sectionHd('Ship To')}
          <div className="fg fg-2" style={{ marginBottom:10 }}>
            <div className="field"><label>Company</label><input value={shipTo.company} onChange={e => setS('company', e.target.value)} /></div>
            <div className="field"><label>Contact Name</label><input value={shipTo.name} onChange={e => setS('name', e.target.value)} /></div>
          </div>
          <div style={{ display:'flex', gap:8, marginBottom:10 }}>
            <div className="field" style={{ flex:'2 1 0' }}><label>Address</label>
              <input value={shipTo.address} onChange={e => setS('address', e.target.value)} /></div>
            <div className="field" style={{ flex:'1.5 1 0' }}><label>City</label>
              <input value={shipTo.city} onChange={e => setS('city', e.target.value)} /></div>
            <div className="field" style={{ width:52 }}><label>State</label>
              <input value={shipTo.state} onChange={e => setS('state', e.target.value)} maxLength={2} style={{ textTransform:'uppercase' }} /></div>
            <div className="field" style={{ width:80 }}><label>ZIP</label>
              <input value={shipTo.zip} onChange={e => setS('zip', e.target.value)} maxLength={5} /></div>
          </div>
          <div style={{ display:'flex', gap:8 }}>
            <div className="field" style={{ width:150 }}><label>Phone</label>
              <input value={shipTo.phone} onChange={e => setS('phone', e.target.value)} /></div>
            <div className="field" style={{ flex:'1 1 0' }}><label>Email</label>
              <input type="email" value={shipTo.email} onChange={e => setS('email', e.target.value)} /></div>
          </div>
        </div>
      )}

      {/* Line Items */}
      {sectionHd('Line Items')}
      <div className="card card-pad" style={{ marginBottom:16 }}>
        <table style={{ width:'100%', borderCollapse:'collapse', fontSize:13 }}>
          <thead>
            <tr style={{ borderBottom:'2px solid var(--g100)' }}>
              <th style={{ textAlign:'left', padding:'4px 8px', color:'var(--g400)', fontWeight:600, width:140 }}>Catalog Item</th>
              <th style={{ textAlign:'left', padding:'4px 8px', color:'var(--g400)', fontWeight:600, width:80 }}>Part #</th>
              <th style={{ textAlign:'left', padding:'4px 8px', color:'var(--g400)', fontWeight:600 }}>Description</th>
              <th style={{ textAlign:'left', padding:'4px 8px', color:'var(--g400)', fontWeight:600, width:110 }}>Billing</th>
              <th style={{ textAlign:'right', padding:'4px 8px', color:'var(--g400)', fontWeight:600, width:70 }}>Qty</th>
              <th style={{ textAlign:'right', padding:'4px 8px', color:'var(--g400)', fontWeight:600, width:95 }}>Unit Price</th>
              <th style={{ textAlign:'right', padding:'4px 8px', color:'var(--g400)', fontWeight:600, width:95 }}>Ext</th>
              <th style={{ width:30 }}></th>
            </tr>
          </thead>
          <tbody>
            {lines.map((line, idx) => (
              <tr key={line._key} style={{ borderBottom:'1px solid var(--g100)' }}>
                <td style={{ padding:'4px 4px' }}>
                  <select style={{ width:'100%', fontSize:13, padding:'7px 9px', border:'1.5px solid var(--g200)', borderRadius:4, background:'#fff' }}
                    value={line.catalogItemId || ''}
                    onChange={e => {
                      const item = catalog.find(c => c.id === e.target.value) || null;
                      pickCatalog(idx, item);
                    }}>
                    <option value="">— custom —</option>
                    {catalog.map(c => (
                      <option key={c.id} value={c.id}>
                        {c.partNumber ? `[${c.partNumber}] ` : ''}{c.description}
                      </option>
                    ))}
                  </select>
                </td>
                <td style={{ padding:'4px 4px' }}>
                  <input style={{ width:'100%', fontSize:13, padding:'7px 9px', border:'1.5px solid var(--g200)', borderRadius:4 }}
                    value={line.partNumber} onChange={e => setLine(idx, 'partNumber', e.target.value)} placeholder="Optional" />
                </td>
                <td style={{ padding:'4px 4px' }}>
                  <input style={{ width:'100%', fontSize:13, padding:'7px 9px', border:'1.5px solid var(--g200)', borderRadius:4 }}
                    value={line.description} onChange={e => setLine(idx, 'description', e.target.value)} placeholder="Description" />
                </td>
                <td style={{ padding:'4px 4px' }}>
                  <select style={{ width:'100%', fontSize:13, padding:'7px 9px', border:'1.5px solid var(--g200)', borderRadius:4, background:'#fff' }}
                    value={line.billingType} onChange={e => setLine(idx, 'billingType', e.target.value)}>
                    {BILLING_TYPES.map(t => <option key={t}>{t}</option>)}
                  </select>
                </td>
                <td style={{ padding:'4px 4px' }}>
                  <input type="number" min="0" step="0.01"
                    style={{ width:'100%', fontSize:13, padding:'7px 9px', border:'1.5px solid var(--g200)', borderRadius:4, textAlign:'right' }}
                    value={line.quantity} onChange={e => setLine(idx, 'quantity', e.target.value)} />
                </td>
                <td style={{ padding:'4px 4px' }}>
                  <input type="number" min="0" step="0.01"
                    style={{ width:'100%', fontSize:13, padding:'7px 9px', border:'1.5px solid var(--g200)', borderRadius:4, textAlign:'right' }}
                    value={line.unitPrice} onChange={e => setLine(idx, 'unitPrice', e.target.value)} placeholder="0.00" />
                </td>
                <td style={{ padding:'4px 8px', textAlign:'right', fontFamily:'monospace', fontSize:12, color:'var(--navy)', whiteSpace:'nowrap' }}>
                  {fmt$(lineExt(line))}
                </td>
                <td style={{ padding:'4px 4px', textAlign:'center' }}>
                  {lines.length > 1 && (
                    <button style={{ background:'none', border:'none', cursor:'pointer', color:'var(--g400)', fontSize:16, lineHeight:1, padding:2 }}
                      onClick={() => removeLine(idx)} title="Remove line">×</button>
                  )}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
        <button className="btn btn-ghost btn-sm" style={{ marginTop:10 }} onClick={addLine}>+ Add Line</button>
      </div>

      {/* Fees & Tax */}
      {sectionHd('Fees, Tax & S/H')}
      <div className="card card-pad" style={{ marginBottom:20 }}>
        <div className="fg fg-4" style={{ marginBottom:0 }}>
          <div className="field">
            <label style={{ display:'flex', alignItems:'center', gap:6, cursor:'pointer' }}>
              <input type="checkbox" checked={tax.isTaxable} onChange={e => setT('isTaxable', e.target.checked)} />
              Taxable
            </label>
          </div>
          {tax.isTaxable && <>
            <div className="field">
              <label>Jurisdiction</label>
              <select value={tax.jurisdiction}
                onChange={e => {
                  const j = e.target.value;
                  const match = taxRates.find(r => r.jurisdiction === j);
                  setTax(t => ({ ...t, jurisdiction: j, taxRate: match ? String(match.rate) : t.taxRate }));
                }}>
                <option value="">— select or enter rate manually —</option>
                {taxRates.map(r => (
                  <option key={r.id} value={r.jurisdiction}>
                    {r.jurisdiction} ({parseFloat(r.rate).toFixed(3)}%)
                  </option>
                ))}
              </select>
            </div>
            <div className="field">
              <label>Tax Rate % <span style={{ fontWeight:400, color:'var(--g400)', fontSize:11 }}>(auto-filled)</span></label>
              <input type="number" min="0" max="100" step="0.001" value={tax.taxRate}
                onChange={e => setT('taxRate', e.target.value)} placeholder="e.g. 8.875" />
            </div>
          </>}
          <div className="field"><label>S&amp;H</label>
            <input type="number" min="0" step="0.01" value={tax.sh}
              onChange={e => setT('sh', e.target.value)} placeholder="0.00" /></div>
        </div>

        {/* Totals summary */}
        <div style={{ marginTop:16, borderTop:'1px solid var(--g100)', paddingTop:14 }}>
          <TotalsSummary totals={totals} />
        </div>
      </div>

      <div style={{ display:'flex', gap:10, justifyContent:'flex-end', marginBottom:30 }}>
        <button className="btn btn-ghost" onClick={onCancel} disabled={saving}>Cancel</button>
        <button className="btn btn-primary" onClick={doSave} disabled={saving}>
          {saving ? 'Saving…' : '💾 Save & Preview'}
        </button>
      </div>
    </div>
    </div>
  );
}

// Small totals block (shared by intake + print preview)
function TotalsSummary({ totals }) {
  const row = (label, val, bold) => (
    <div style={{ display:'flex', justifyContent:'space-between', marginBottom:4, fontWeight: bold ? 700 : 400, fontSize:13, color: bold ? 'var(--navy)' : 'var(--g600)' }}>
      <span>{label}</span>
      <span style={{ fontFamily:'monospace' }}>{fmt$(val)}</span>
    </div>
  );
  return (
    <div style={{ maxWidth:320, marginLeft:'auto' }}>
      {row('First Month Fees',   totals.firstMonth)}
      {row('Last Month Fees',    totals.lastMonth)}
      {row('One-Time Fees',      totals.oneTimeFees)}
      {row('S&H',                totals.sh)}
      {totals.tax > 0 && row('Sales Tax', totals.tax)}
      <div style={{ borderTop:'2px solid var(--navy)', marginTop:6, paddingTop:6 }}>
        {row('Deposit Amount Due', totals.deposit, true)}
      </div>
    </div>
  );
}

// Produces a unique order number: Excel date serial (days since Dec 30 1899)
// concatenated with HHMM in local time.  Example: 461381423
// Unique to the minute; never repeats in practice.
function toOrderNumber(createdAt) {
  const d   = createdAt ? new Date(createdAt) : new Date();
  const pad = n => String(n).padStart(2, '0');
  const dateSerial = Math.floor(d.getTime() / 86400000 + 25569);
  const hhmm       = `${pad(d.getHours())}${pad(d.getMinutes())}`;
  return `${dateSerial}${hhmm}`;
}

// ══════════════════════════════════════════════════════════
// ORDER FORM PREVIEW (printable)
// ══════════════════════════════════════════════════════════
function OrderFormPreview({ form, account, onBack, onNewForm, showToast }) {
  const totals = calcTotals(
    (form.lines || []),
    form.shipAndHandle, form.taxRate, form.isTaxable
  );
  const orderNum = toOrderNumber(form.createdAt);

  useEffect(() => {
    const style = document.createElement('style');
    style.id = 'of-print-style';
    style.textContent = `
      @media print {
        body * { visibility: hidden !important; }
        #of-page, #of-page * { visibility: visible !important; }
        #of-page {
          position: absolute !important;
          top: 0 !important;
          left: 0 !important;
          width: 100% !important;
          max-width: none !important;
          margin: 0 !important;
          padding: 12px !important;
          box-shadow: none !important;
          border-radius: 0 !important;
        }
        @page {
          size: auto;
          margin: 8mm;
        }
      }
    `;
    document.head.appendChild(style);
    return () => { const el = document.getElementById('of-print-style'); if (el) el.remove(); };
  }, []);

  const doPrint = () => {
    // Scale the page to fit the printable area so nothing gets clipped
    const el = document.getElementById('of-page');
    if (el) el.style.zoom = '0.85';
    window.print();
    if (el) el.style.zoom = '';
  };

  // Email the order form: rasterize the page to a PDF and open the shared
  // email modal with it pre-attached.
  const [emailFile, setEmailFile] = useState(null);
  const [pdfBusy,   setPdfBusy]   = useState(false);

  // E-signature: email the customer a secure sign link (sign.html?t=token)
  // plus a PDF of the order so they can also print + sign the old way.
  const [signBusy, setSignBusy] = useState(false);
  const sendForSign = async () => {
    const email = (prompt('Send the signature request to:', form.billToEmail || '') || '').trim();
    if (!email) return;
    const message = (prompt('Optional note to include in the email (leave blank for none):') || '').trim();
    setSignBusy(true);
    try {
      let pdfFile = null;
      try {
        const safe = String(form.billToCompany || account?.companyName || 'order').replace(/[^\w-]+/g, '_').slice(0, 40);
        pdfFile = await captureDocumentPdf('#of-page', `OrderForm-${orderNum}-${safe}.pdf`);
      } catch { /* PDF is a bonus — the sign link still goes out without it */ }
      const r = await CRM.OrderFormsAPI.sendSign(form.id, email, message || null, pdfFile);
      showToast(`Signature request sent to ${r.to}${pdfFile ? ' (PDF attached)' : ''}.`, 'success');
    } catch (e) {
      showToast('Send failed: ' + e.message, 'error');
    } finally { setSignBusy(false); }
  };
  const doEmail = async () => {
    setPdfBusy(true);
    try {
      const safe = String(form.billToCompany || account?.companyName || 'order').replace(/[^\w-]+/g, '_').slice(0, 40);
      setEmailFile(await captureDocumentPdf('#of-page', `OrderForm-${orderNum}-${safe}.pdf`));
    } catch (e) { showToast('Could not build the PDF: ' + e.message, 'error'); }
    finally { setPdfBusy(false); }
  };

  // Offline sign-off: record a returned paper copy (optionally with the scan)
  const [offlineOpen, setOfflineOpen] = useState(false);
  const [offBusy, setOffBusy] = useState(false);
  const [off, setOff] = useState({ name:'', title:'', date: new Date().toISOString().split('T')[0] });
  const offFileRef = React.useRef();
  const saveOffline = async () => {
    if (!off.name.trim()) { showToast('Enter the signer\'s name.', 'error'); return; }
    setOffBusy(true);
    try {
      const r = await CRM.OrderFormsAPI.signOffline(form.id, off.name.trim(), off.title.trim() || null,
        off.date || null, offFileRef.current?.files?.[0] || null);
      showToast(`Recorded — signed on paper by ${off.name.trim()}${r.scan ? ` (scan "${r.scan}" attached)` : ''}` +
        (r.salesRecorded ? ` · $${Number(r.salesTotal).toLocaleString()} logged as sales` : '') + '.', 'success');
      setOfflineOpen(false);
      Object.assign(form, { signedAt: r.signedAt, signedByName: off.name.trim(),
        signedByTitle: off.title.trim() || null, signedMethod: 'offline', signedScanName: r.scan || null });
    } catch (e) {
      showToast('Failed: ' + e.message, 'error');
    } finally { setOffBusy(false); }
  };

  const orderDateFmt = form.orderDate
    ? new Date(form.orderDate + 'T00:00:00').toLocaleDateString('en-US', { year:'numeric', month:'long', day:'numeric' })
    : '';

  const shipTo = form.shipSameAsBill
    ? { company: form.billToCompany, name: form.billToName, address: form.billToAddress, city: form.billToCity, state: form.billToState, zip: form.billToZip, phone: form.billToPhone, email: form.billToEmail }
    : { company: form.shipToCompany, name: form.shipToName, address: form.shipToAddress, city: form.shipToCity, state: form.shipToState, zip: form.shipToZip, phone: form.shipToPhone, email: form.shipToEmail };

  const addrBlock = (obj) => {
    const parts = [];
    if (obj.company) parts.push(<div key="co" style={{ fontWeight:600 }}>{obj.company}</div>);
    if (obj.name)    parts.push(<div key="nm">{obj.name}</div>);
    if (obj.address) parts.push(<div key="ad">{obj.address}</div>);
    const csz = [obj.city, obj.state && obj.zip ? `${obj.state} ${obj.zip}` : (obj.state || obj.zip)].filter(Boolean).join(', ');
    if (csz)         parts.push(<div key="csz">{csz}</div>);
    if (obj.phone)   parts.push(<div key="ph">{obj.phone}</div>);
    if (obj.email)   parts.push(<div key="em" style={{ color:'#2563EB' }}>{obj.email}</div>);
    return parts.length > 0 ? parts : <div style={{ color:'#9AA3B0' }}>—</div>;
  };

  const cell = (label, value) => (
    <div style={{ marginBottom:6 }}>
      <div style={{ fontSize:10, color:'#9AA3B0', fontWeight:600, textTransform:'uppercase', letterSpacing:'0.04em' }}>{label}</div>
      <div style={{ fontSize:12, color:'#1E293B', marginTop:1 }}>{value || '—'}</div>
    </div>
  );

  return (
    <div id="of-overlay" style={{ position:'fixed', inset:0, background:'rgba(0,0,0,0.5)', zIndex:9000, overflowY:'auto', padding:'30px 20px 80px' }}>
      {/* Print bar */}
      <div id="of-print-bar" style={{ position:'fixed', bottom:0, left:0, right:0, background:'#162534', padding:'12px 24px', display:'flex', justifyContent:'space-between', alignItems:'center', zIndex:9001 }}>
        <div style={{ display:'flex', gap:10 }}>
          <button className="btn" style={{ background:'transparent', color:'#fff', border:'1px solid rgba(255,255,255,0.5)' }} onClick={onBack}>← Back to Orders</button>
          {onNewForm && <button className="btn" style={{ background:'transparent', color:'#fff', border:'1px solid rgba(255,255,255,0.5)' }} onClick={onNewForm}>+ New Order Form</button>}
        </div>
        <div style={{ display:'flex', gap:10, alignItems:'center' }}>
          {form.signedAt ? (
            <span style={{ background:'#F0FDF4', color:'#166534', border:'1px solid #BBF7D0', borderRadius:6, padding:'8px 14px', fontSize:13, fontWeight:700 }}>
              ✔ Signed {form.signedMethod === 'offline' ? 'on paper' : 'online'} by {form.signedByName} · {new Date(form.signedAt).toLocaleDateString()}
              {form.signedScanName && (
                <a href={`/api/order-forms/${form.id}/signed-scan`} target="_blank" rel="noopener"
                  style={{ marginLeft:8, color:'#166534', textDecoration:'underline', fontWeight:600 }}>view scan</a>
              )}
            </span>
          ) : (
            <React.Fragment>
              <button className="btn" style={{ background:'transparent', color:'#fff', border:'1px solid rgba(255,255,255,0.5)', fontSize:13 }}
                onClick={() => setOfflineOpen(true)}>📄 Signed on paper?</button>
              <button className="btn" style={{ background:'#BC141E', color:'#fff', fontSize:15, padding:'10px 22px' }}
                onClick={sendForSign} disabled={signBusy}>
                {signBusy ? 'Sending…' : (form.sentAt ? '✍ Re-send for signature' : '✍ Send for signature')}
              </button>
            </React.Fragment>
          )}
          <button className="btn" style={{ background:'transparent', color:'#fff', border:'1px solid rgba(255,255,255,0.5)', fontSize:15, padding:'10px 22px' }}
            onClick={doEmail} disabled={pdfBusy}>{pdfBusy ? 'Preparing PDF…' : '✉ Email'}</button>
          <button className="btn btn-primary" style={{ background:'#E8F2FF', color:'#162534', fontSize:15, padding:'10px 28px' }} onClick={doPrint}>🖨 Print / Save PDF</button>
        </div>
      </div>

      {/* Page */}
      <div id="of-page" style={{ background:'#fff', maxWidth:820, margin:'0 auto', padding:'32px 36px', boxShadow:'0 8px 32px rgba(0,0,0,0.18)', borderRadius:4, fontFamily:'Arial, sans-serif', fontSize:12, color:'#1E293B', lineHeight:1.4 }}>

        {/* Header */}
        <div style={{ display:'flex', justifyContent:'space-between', alignItems:'flex-start', marginBottom:20, paddingBottom:16, borderBottom:'3px solid #162534' }}>
          <div>
            {CRM.companyLogo
              ? <img src={CRM.companyLogo} alt="Company logo" style={{ maxHeight:60, maxWidth:200, objectFit:'contain', marginBottom:4 }} />
              : <div style={{ fontSize:22, fontWeight:900, color:'#162534', letterSpacing:'-0.02em' }}>{CRM.companyName || 'CTR/NY'}</div>
            }
            {!CRM.companyLogo && CRM.companyName && (
              <div style={{ fontSize:11, color:'#64748B', marginTop:2 }}>{CRM.companyName}</div>
            )}
            <div style={{ fontSize:11, color:'#64748B', marginTop: CRM.companyLogo ? 4 : 2 }}>Time &amp; Attendance / Labor Management</div>
            <div style={{ fontSize:11, color:'#64748B' }}>Tel: 1.800.777.5226 | Fax: 212.260.3852</div>
            <div style={{ fontSize:11, color:'#64748B' }}>sales@ctrny.com | www.ctrny.com</div>
          </div>
          <div style={{ textAlign:'right' }}>
            <div style={{ fontSize:20, fontWeight:800, color:'#162534', letterSpacing:'0.04em' }}>SALES AGREEMENT</div>
            {orderNum && <div style={{ fontSize:13, fontWeight:700, color:'#162534', marginTop:3, letterSpacing:'0.06em' }}>#{orderNum}</div>}
            {orderDateFmt && <div style={{ fontSize:11, color:'#64748B', marginTop:4 }}>Date: {orderDateFmt}</div>}
            {form.custPo    && <div style={{ fontSize:11, color:'#64748B' }}>Cust PO: {form.custPo}</div>}
            {form.salesRepName && <div style={{ fontSize:11, color:'#64748B' }}>Rep: {form.salesRepName}</div>}
          </div>
        </div>

        {/* Order details bar */}
        {form.terms && (
          <div style={{ background:'#F8FAFC', border:'1px solid #E2E8F0', borderRadius:4, padding:'8px 12px', marginBottom:16, fontSize:11, color:'#475569' }}>
            <span style={{ fontWeight:700, color:'#162534', textTransform:'uppercase', fontSize:10, letterSpacing:'0.06em' }}>Terms: </span>{form.terms}
          </div>
        )}

        {/* Bill To / Ship To */}
        <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:16, marginBottom:16 }}>
          <div style={{ border:'1px solid #E2E8F0', borderRadius:4, padding:'10px 12px' }}>
            <div style={{ fontSize:10, color:'#9AA3B0', fontWeight:700, textTransform:'uppercase', letterSpacing:'0.06em', marginBottom:6 }}>Bill To</div>
            <div style={{ fontSize:12, lineHeight:1.6 }}>{addrBlock({ company:form.billToCompany, name:form.billToName, address:form.billToAddress, city:form.billToCity, state:form.billToState, zip:form.billToZip, phone:form.billToPhone, email:form.billToEmail })}</div>
          </div>
          <div style={{ border:'1px solid #E2E8F0', borderRadius:4, padding:'10px 12px' }}>
            <div style={{ fontSize:10, color:'#9AA3B0', fontWeight:700, textTransform:'uppercase', letterSpacing:'0.06em', marginBottom:6 }}>
              Ship To {form.shipSameAsBill && <span style={{ fontWeight:400, textTransform:'none', fontSize:10 }}>(same as bill to)</span>}
            </div>
            <div style={{ fontSize:12, lineHeight:1.6 }}>{addrBlock(shipTo)}</div>
          </div>
        </div>

        {/* Line items table */}
        <table style={{ width:'100%', borderCollapse:'collapse', marginBottom:16, fontSize:12 }}>
          <thead>
            <tr style={{ background:'#162534', color:'#fff' }}>
              <th style={{ padding:'8px 10px', textAlign:'left',  fontWeight:600, width:90  }}>Part #</th>
              <th style={{ padding:'8px 10px', textAlign:'left',  fontWeight:600            }}>Description</th>
              <th style={{ padding:'8px 10px', textAlign:'center',fontWeight:600, width:90  }}>Billing</th>
              <th style={{ padding:'8px 10px', textAlign:'right', fontWeight:600, width:50  }}>Qty</th>
              <th style={{ padding:'8px 10px', textAlign:'right', fontWeight:600, width:90  }}>Unit Price</th>
              <th style={{ padding:'8px 10px', textAlign:'right', fontWeight:600, width:90  }}>Extended</th>
            </tr>
          </thead>
          <tbody>
            {(form.lines || []).map((line, idx) => (
              <tr key={line.id || idx} style={{ background: idx % 2 === 0 ? '#fff' : '#F8FAFC', borderBottom:'1px solid #E2E8F0' }}>
                <td style={{ padding:'7px 10px', fontFamily:'monospace', color:'#64748B', fontSize:11 }}>{line.partNumber || '—'}</td>
                <td style={{ padding:'7px 10px' }}>{line.description}</td>
                <td style={{ padding:'7px 10px', textAlign:'center', color:'#64748B' }}>{line.billingType}</td>
                <td style={{ padding:'7px 10px', textAlign:'right' }}>{line.quantity}</td>
                <td style={{ padding:'7px 10px', textAlign:'right', fontFamily:'monospace' }}>{fmt$(line.unitPrice)}</td>
                <td style={{ padding:'7px 10px', textAlign:'right', fontFamily:'monospace', fontWeight:600 }}>{fmt$(lineExt(line))}</td>
              </tr>
            ))}
          </tbody>
        </table>

        {/* Totals + Notes columns */}
        <div style={{ display:'grid', gridTemplateColumns:'1fr auto', gap:24, marginBottom:20 }}>
          {/* Notes / tax info */}
          <div style={{ fontSize:11, color:'#64748B' }}>
            {form.isTaxable && form.taxId && <div>Tax ID: {form.taxId}</div>}
            {form.leadSource && <div>Lead Source: {form.leadSource}</div>}
          </div>
          {/* Totals */}
          <div style={{ minWidth:220 }}>
            {[
              ['First Month Fees',  totals.firstMonth,  false],
              ['Last Month Fees',   totals.lastMonth,   false],
              ['One-Time Fees',     totals.oneTimeFees, false],
              ['S&H',               totals.sh,          false],
              ...(totals.tax > 0 ? [['Sales Tax', totals.tax, false]] : []),
            ].map(([label, val]) => (
              <div key={label} style={{ display:'flex', justifyContent:'space-between', padding:'3px 0', fontSize:12, color:'#475569', borderBottom:'1px solid #F1F5F9' }}>
                <span>{label}</span>
                <span style={{ fontFamily:'monospace', marginLeft:24 }}>{fmt$(val)}</span>
              </div>
            ))}
            <div style={{ display:'flex', justifyContent:'space-between', alignItems:'baseline', padding:'6px 0 4px', fontSize:14, fontWeight:800, color:'#162534', borderTop:'2px solid #162534', marginTop:4 }}>
              <span>Deposit Amount Due</span>
              <span style={{ fontFamily:'monospace', marginLeft:48 }}>{fmt$(totals.deposit)}</span>
            </div>
          </div>
        </div>

        {/* Legal terms */}
        <div style={{ marginTop:20, padding:'10px 12px', background:'#F8FAFC', border:'1px solid #E2E8F0', borderRadius:4, fontSize:8.5, color:'#475569', lineHeight:1.6 }}>
          The undersigned Customer hereby acknowledges that: (a) the undersigned is duly authorized by Customer to contractually bind it; (b) on behalf of Customer, the undersigned has read and agrees to the CTRNY Terms and conditions located at:{' '}
          <span style={{ color:'#2563EB' }}>https://www.ctrny.com/terms-and-conditions</span>{' '}
          which are incorporated by this reference and form a binding agreement between Customer and CTRNY; and (c) Customer agrees to review the terms and conditions periodically for any changes. Deposit checks are non-refundable. Order subject to applicable tax &amp; freight charges. Prices valid for 30 days.
        </div>

        {/* Signature block */}
        <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:24, marginTop:16, paddingTop:16, borderTop:'1px solid #E2E8F0' }}>
          <div>
            <div style={{ fontSize:10, color:'#9AA3B0', fontWeight:600, textTransform:'uppercase', letterSpacing:'0.04em', marginBottom: form.signedAt ? 6 : 20 }}>Authorized Signature (Customer)</div>
            {form.signedAt ? (
              <div>
                {form.signatureImage && <img src={form.signatureImage} alt="signature" style={{ maxHeight:46, maxWidth:220, display:'block' }} />}
                <div style={{ borderBottom:'1px solid #1E293B', marginBottom:6 }}></div>
                <div style={{ display:'flex', justifyContent:'space-between', fontSize:10, color:'#1E293B' }}>
                  <span style={{ fontWeight:700 }}>{form.signedByName}{form.signedByTitle ? `, ${form.signedByTitle}` : ''}</span>
                  <span>{new Date(form.signedAt).toLocaleDateString()}</span>
                </div>
                <div style={{ fontSize:9, color:'#94A3B8', marginTop:2 }}>
                  {form.signedMethod === 'offline' ? 'Signed on paper — copy on file' : 'Signed electronically via secure link'}
                </div>
              </div>
            ) : (
              <div>
                <div style={{ borderBottom:'1px solid #1E293B', marginBottom:6, height:24 }}></div>
                <div style={{ display:'flex', justifyContent:'space-between', fontSize:10, color:'#64748B' }}>
                  <span>Signature / Title</span>
                  <span>Date</span>
                </div>
              </div>
            )}
          </div>
          <div>
            <div style={{ fontSize:10, color:'#9AA3B0', fontWeight:600, textTransform:'uppercase', letterSpacing:'0.04em', marginBottom:20 }}>Accepted by CTR/NY</div>
            <div style={{ borderBottom:'1px solid #1E293B', marginBottom:6, height:24 }}></div>
            <div style={{ display:'flex', justifyContent:'space-between', fontSize:10, color:'#64748B' }}>
              <span>Signature / Title</span>
              <span>Date</span>
            </div>
          </div>
        </div>

        {/* Footer */}
        <div style={{ marginTop:20, paddingTop:12, borderTop:'1px solid #E2E8F0', fontSize:10, color:'#94A3B8', textAlign:'center' }}>
          CTR/NY · Time &amp; Attendance / Labor Management · 1.800.777.5226 · sales@ctrny.com · www.ctrny.com
          {form.createdAt && (
            <div style={{ marginTop:4, fontSize:9, color:'#B0B7C3' }}>
              Order locked at save — snapshot captured {new Date(form.createdAt).toLocaleString()}
            </div>
          )}
        </div>
      </div>

      {offlineOpen && (
        <div style={{ position:'fixed', inset:0, background:'rgba(0,0,0,0.55)', zIndex:9500, display:'flex', alignItems:'center', justifyContent:'center', padding:20 }}
          onClick={() => setOfflineOpen(false)}>
          <div style={{ background:'#fff', borderRadius:12, padding:'24px 28px', width:'min(440px,100%)', fontFamily:'var(--font)' }}
            onClick={e => e.stopPropagation()}>
            <div style={{ fontSize:16, fontWeight:800, color:'var(--navy)', marginBottom:4 }}>Record paper sign-off</div>
            <div style={{ fontSize:12, color:'var(--g600)', marginBottom:16 }}>
              The customer signed a printed copy. Record who signed and, if you have it, attach the scan — it's kept on the order as the executed document.
            </div>
            <div className="field"><label>Signer's name *</label>
              <input value={off.name} onChange={e => setOff(o => ({...o, name: e.target.value}))} placeholder="As written on the paper copy" /></div>
            <div className="fg fg-2">
              <div className="field"><label>Title</label>
                <input value={off.title} onChange={e => setOff(o => ({...o, title: e.target.value}))} /></div>
              <div className="field"><label>Date signed</label>
                <input type="date" value={off.date} onChange={e => setOff(o => ({...o, date: e.target.value}))} /></div>
            </div>
            <div className="field"><label>Scan of the signed copy <span style={{fontWeight:400,color:'var(--g400)'}}>(optional, PDF or image)</span></label>
              <input type="file" ref={offFileRef} accept=".pdf,image/*" /></div>
            <div style={{ display:'flex', justifyContent:'flex-end', gap:8, marginTop:18 }}>
              <button className="btn btn-ghost" onClick={() => setOfflineOpen(false)}>Cancel</button>
              <button className="btn btn-primary" onClick={saveOffline} disabled={offBusy}>
                {offBusy ? 'Saving…' : '✔ Record sign-off'}
              </button>
            </div>
          </div>
        </div>
      )}

      {emailFile && (
        <SendEmailModal
          toEmail={form.billToEmail || shipTo.email || ''}
          toName={form.billToName || form.billToCompany || ''}
          accountId={form.accountId || account?.id || null}
          initialFiles={[emailFile]}
          initialSubject={`Order Form #${orderNum} — ${form.billToCompany || ''}`.trim()}
          zIndex={9500}
          onClose={() => setEmailFile(null)}
          showToast={showToast}
        />
      )}
    </div>
  );
}

Object.assign(window, { OrderCatalogAdmin, AccountOrderFormsTab, OrderFormIntake, OrderFormPreview });
