// Create new order — multi-step wizard

const WIZARD_STEPS = [
  { id: 'products', label: 'Products',        th: 'เลือกบริการ' },
  { id: 'company',  label: 'Company',         th: 'บริษัทลูกค้า' },
  { id: 'contact',  label: 'Contact',         th: 'ผู้ติดต่อ' },
  { id: 'docs',     label: 'Documents',       th: 'เอกสารแนบ' },
  { id: 'review',   label: 'Review & submit', th: 'ตรวจสอบและส่ง' },
];

const CreateOrderView = ({ tweaks, onBack, onComplete, preselect }) => {
  // Products is now step 0, so preselect always starts at 0
  const [step, setStep] = useState(0);
  const [submitting, setSubmitting] = useState(false);
  const [submitError, setSubmitError] = useState('');
  const [draft, setDraft] = useState(() => {
    const baseItems = preselect
      ? [{ productId: preselect.productId, packageId: preselect.packageId, qty: preselect.qty || 1 }]
      : [];
    return {
      customerType: 'existing',
      companyId: null,
      company: null,
      items: baseItems,
      contact: {},
      docs: [],
      contractMonths: 12,
      startDate: 'asap',
      notes: '',
    };
  });

  const next = () => setStep(s => Math.min(s + 1, WIZARD_STEPS.length - 1));
  const prev = () => setStep(s => Math.max(s - 1, 0));

  // ── Shared: build order payload (used by both save-draft & submit) ──────────
  const buildOrderPayload = async () => {
    const prods = window.PRODUCTS || PRODUCTS || [];
    const year = new Date().getFullYear();
    const allOrders = window.ORDERS || ORDERS || [];
    const nums = allOrders.map(o => parseInt((o.id || '').replace(/\D/g,'').slice(-4))).filter(n => !isNaN(n) && n > 0);
    const nextNum = String((nums.length ? Math.max(...nums) : 188) + 1).padStart(4, '0');
    const orderId = `SOL-${year}-${nextNum}`;

    let companyId = draft.company?.id;
    if (draft.customerType === 'new') {
      const cid = `c_${Date.now()}`;
      const cr = await window.apiFetch('/api/companies', {
        method: 'POST',
        body: JSON.stringify({
          id: cid,
          name: draft.company?.name || '',
          tax_id: draft.company?.taxId || '',
          sector: draft.company?.sector || '',
          size: draft.company?.size || '',
          province: draft.company?.province || '',
        }),
      });
      if (!cr.ok) { const e = await cr.json(); throw new Error(e.error || 'ไม่สามารถสร้างบริษัทได้'); }
      companyId = cid;
    }

    let contactId = null;
    if (draft.contact?.id) {
      // Existing contact — use its ID directly
      contactId = draft.contact.id;
    } else if (draft.contact?.name?.trim()) {
      // New contact filled in by user — create it
      try {
        const cr = await window.apiFetch('/api/contacts', {
          method: 'POST',
          body: JSON.stringify({
            companyId,
            name:        draft.contact.name,
            role:        draft.contact.role        || '',
            email:       draft.contact.email       || '',
            phone:       draft.contact.phone       || '',
            mobile:      draft.contact.mobile      || '',
            contactType: draft.contact.contactType || 'Primary',
          }),
        });
        if (cr.ok) { const ct = await cr.json(); contactId = ct.id; }
      } catch {}
    } else {
      const contacts = window.CONTACTS || CONTACTS || {};
      contactId = contacts[companyId]?.id || null;
    }

    let ownerId = null;
    try {
      const me = await window.apiFetch('/api/auth/me').then(r => r.ok ? r.json() : null);
      ownerId = me?.id || null;
    } catch {}

    const items = (draft.items || []).map(it => {
      const prod = prods.find(p => p.id === it.productId);
      const pkg  = prod?.packages?.find(p => p.id === it.packageId);
      return { product_id: it.productId, package_id: it.packageId, qty: it.qty, unit_price: pkg?.price || 0 };
    });

    return { orderId, companyId, contactId, ownerId, items };
  };

  // ── Save as Draft ───────────────────────────────────────────────────────────
  const handleSaveDraft = async () => {
    if (!draft.items?.length) { setSubmitError('กรุณาเลือกสินค้าอย่างน้อย 1 รายการ'); return; }
    setSubmitting(true);
    setSubmitError('');
    try {
      const { orderId, companyId, contactId, ownerId, items } = await buildOrderPayload();
      if (!companyId) throw new Error('กรุณาเลือกหรือกรอกข้อมูลบริษัทลูกค้า');

      // Create order with status = draft (no submit)
      const r = await window.apiFetch('/api/orders', {
        method: 'POST',
        body: JSON.stringify({ id: orderId, company_id: companyId, contact_id: contactId, contract_months: draft.contractMonths || 12, owner_id: ownerId, items, notes: draft.notes || null }),
      });
      if (!r.ok) { const e = await r.json(); throw new Error(e.error || 'ไม่สามารถสร้าง order ได้'); }

      // Save documents — upload actual file when available, else metadata-only
      for (const d of (draft.docs || [])) {
        if (d.file) {
          const fd = new FormData();
          fd.append('file', d.file);
          if (d.docId) fd.append('doc_type_id', d.docId);
          await fetch(`/api/orders/${orderId}/documents/upload`, {
            method: 'POST',
            headers: { Authorization: `Bearer ${localStorage.getItem('sol_auth_token')}` },
            body: fd,
          }).catch(() => {});
        } else {
          await window.apiFetch(`/api/orders/${orderId}/documents`, {
            method: 'POST', body: JSON.stringify({ docs: [{ filename: d.name, size: d.size || null, doc_type_id: d.docId || null }] }),
          }).catch(() => {});
        }
      }

      await window.apiFetch(`/api/orders/${orderId}/activities`, {
        method: 'POST', body: JSON.stringify({ action: 'created' }),
      }).catch(() => {});

      // Refresh global data
      try {
        const initData = await window.apiFetch('/api/init').then(r => r.ok ? r.json() : null);
        if (initData) {
          if (initData.orders)    window.ORDERS    = initData.orders;
          if (initData.companies) window.COMPANIES = initData.companies;
          if (initData.contacts)  window.CONTACTS  = initData.contacts;
        }
      } catch {}

      showToast(`บันทึก Draft ${orderId} แล้ว`, { variant: 'success', detail: 'สามารถกลับมา Submit ได้ภายหลัง' });
      onComplete && onComplete();
    } catch (err) {
      setSubmitError(err.message);
    } finally {
      setSubmitting(false);
    }
  };

  // ── Submit handler ──────────────────────────────────────────────────────────
  const handleSubmit = async () => {
    setSubmitting(true);
    setSubmitError('');
    try {
      const { orderId, companyId, contactId, ownerId, items } = await buildOrderPayload();
      if (!companyId) throw new Error('กรุณาเลือกหรือกรอกข้อมูลบริษัทลูกค้า');

      // Create order (status: draft)
      const r = await window.apiFetch('/api/orders', {
        method: 'POST',
        body: JSON.stringify({ id: orderId, company_id: companyId, contact_id: contactId, contract_months: draft.contractMonths || 12, owner_id: ownerId, items, notes: draft.notes || null }),
      });
      if (!r.ok) { const e = await r.json(); throw new Error(e.error || 'ไม่สามารถสร้าง order ได้'); }

      // Save uploaded documents — upload actual file when available
      for (const d of (draft.docs || [])) {
        if (d.file) {
          const fd = new FormData();
          fd.append('file', d.file);
          if (d.docId) fd.append('doc_type_id', d.docId);
          await fetch(`/api/orders/${orderId}/documents/upload`, {
            method: 'POST',
            headers: { Authorization: `Bearer ${localStorage.getItem('sol_auth_token')}` },
            body: fd,
          }).catch(() => {});
        } else {
          await window.apiFetch(`/api/orders/${orderId}/documents`, {
            method: 'POST', body: JSON.stringify({ docs: [{ filename: d.name, size: d.size || null, doc_type_id: d.docId || null }] }),
          }).catch(() => {});
        }
      }

      // Log created activity
      await window.apiFetch(`/api/orders/${orderId}/activities`, {
        method: 'POST', body: JSON.stringify({ action: 'created' }),
      }).catch(() => {});

      // Submit order (draft → submitted)
      const sr = await window.apiFetch(`/api/orders/${orderId}/status`, {
        method: 'PATCH',
        body: JSON.stringify({ status: 'submitted' }),
      });
      if (!sr.ok) throw new Error('ไม่สามารถ submit order ได้');

      await window.apiFetch(`/api/orders/${orderId}/activities`, {
        method: 'POST', body: JSON.stringify({ action: 'submitted' }),
      }).catch(() => {});

      // Refresh global data so orders list reflects the new order
      try {
        const initData = await window.apiFetch('/api/init').then(r => r.ok ? r.json() : null);
        if (initData) {
          if (initData.orders)    window.ORDERS    = initData.orders;
          if (initData.companies) window.COMPANIES = initData.companies;
          if (initData.contacts)  window.CONTACTS  = initData.contacts;
        }
      } catch {}

      showToast(`Order ${orderId} สร้างเรียบร้อย`, { variant: 'success', detail: 'Order submitted — เข้าสู่ขั้นตอน Pending approval' });
      onComplete && onComplete();
    } catch (err) {
      setSubmitError(err.message);
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <>
      {/* Breadcrumb */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 11.5, color: 'var(--ink-3)', marginBottom: 10 }}>
        <button onClick={onBack} style={{
          background: 'none', border: 'none', cursor: 'pointer', color: 'var(--ink-3)',
          fontFamily: 'Kanit, sans-serif', fontSize: 11.5, padding: 0,
          display: 'inline-flex', alignItems: 'center', gap: 4,
        }}>
          <Icon name="chevronLeft" size={11}/> Orders
        </button>
        <Icon name="chevron" size={9}/>
        <span>New order</span>
      </div>

      <h1 style={{ fontSize: 22, fontWeight: 500, letterSpacing: '-0.01em', margin: '0 0 4px' }}>สร้างคำสั่งซื้อใหม่</h1>
      <div style={{ fontSize: 12, color: 'var(--ink-3)', marginBottom: 20 }}>กรอกข้อมูลลูกค้าและเลือกบริการ Solutions ที่ต้องการสมัคร</div>

      <div style={{ display: 'grid', gridTemplateColumns: '220px 1fr', gap: 20 }}>
        {/* Step list (left) */}
        <div style={{ background: 'var(--panel)', border: '1px solid var(--line)', borderRadius: 4, padding: 12, alignSelf: 'flex-start', position: 'sticky', top: 76 }}>
          <div className="eyebrow" style={{ padding: '4px 8px 8px' }}>Order setup</div>
          {WIZARD_STEPS.map((s, i) => {
            const done = i < step;
            const active = i === step;
            return (
              <button key={s.id} onClick={() => done && setStep(i)}
                disabled={!done && !active}
                style={{
                  display: 'flex', alignItems: 'center', gap: 10,
                  padding: '8px 10px', width: '100%', textAlign: 'left',
                  background: active ? 'var(--bg-2)' : 'transparent',
                  border: 'none', borderRadius: 3, cursor: done ? 'pointer' : 'default',
                  fontFamily: 'Kanit, sans-serif', fontSize: 12.5,
                  color: active ? 'var(--ink)' : done ? 'var(--ink-2)' : 'var(--ink-3)',
                }}>
                <span style={{
                  width: 20, height: 20, borderRadius: '50%',
                  background: done ? 'var(--positive)' : active ? 'var(--ink)' : 'var(--panel)',
                  border: done || active ? 'none' : '1.5px solid var(--line-3)',
                  color: '#fff', display: 'grid', placeItems: 'center', fontSize: 10.5, fontWeight: 600,
                  flexShrink: 0, fontFamily: 'IBM Plex Mono',
                }}>
                  {done ? <Icon name="check" size={10}/> : i + 1}
                </span>
                <div style={{ minWidth: 0 }}>
                  <div style={{ fontWeight: active ? 500 : 400 }}>{s.label}</div>
                  <div style={{ fontSize: 10.5, color: 'var(--ink-3)' }}>{s.th}</div>
                </div>
              </button>
            );
          })}
        </div>

        {/* Step body */}
        <div>
          {/* Order summary bar — steps 2–5 only */}
          {step > 0 && draft.items.length > 0 && (() => {
            const prods = window.PRODUCTS || PRODUCTS || [];
            const items = draft.items.map(it => {
              const product = prods.find(p => p.id === it.productId);
              const pkg = product?.packages?.find(p => p.id === it.packageId);
              return { product, pkg, qty: it.qty };
            }).filter(x => x.product && x.pkg);
            if (!items.length) return null;
            return (
              <div style={{
                display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap',
                padding: '8px 12px', marginBottom: 8,
                background: 'var(--bg-2)', border: '1px solid var(--line)', borderRadius: 4,
              }}>
                <span style={{ fontSize: 10, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.07em', flexShrink: 0 }}>Ordering</span>
                <span style={{ color: 'var(--line-3)' }}>·</span>
                {items.map(({ product, pkg, qty }, i) => (
                  <React.Fragment key={product.id}>
                    {i > 0 && <span style={{ color: 'var(--line-3)', fontSize: 11 }}>+</span>}
                    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}>
                      <ProductGlyph productId={product.id} size={18}/>
                      <span style={{ fontSize: 12.5, fontWeight: 500 }}>{product.name}</span>
                      <span style={{ fontSize: 11, color: 'var(--ink-3)' }}>·</span>
                      <span style={{ fontSize: 12, color: 'var(--ink-2)' }}>{pkg.name}</span>
                      <span className="num" style={{ fontSize: 11, color: 'var(--ink-3)' }}>฿{(pkg.price * qty).toLocaleString()}/{pkg.billingPeriod === 'yearly' ? 'yr' : 'mo'}</span>
                    </span>
                  </React.Fragment>
                ))}
              </div>
            );
          })()}
          <div style={{ background: 'var(--panel)', border: '1px solid var(--line)', borderRadius: 4, minHeight: 480 }}>
            {step === 0 && <ProductsStep draft={draft} setDraft={setDraft} tweaks={tweaks}/>}
            {step === 1 && <CompanyStep draft={draft} setDraft={setDraft}/>}
            {step === 2 && <ContactStep draft={draft} setDraft={setDraft}/>}
            {step === 3 && <DocsStep draft={draft} setDraft={setDraft}/>}
            {step === 4 && <ReviewStep draft={draft} setDraft={setDraft} tweaks={tweaks}/>}
          </div>

          {/* Footer nav */}
          {(() => {
            // Validate required docs on step 3
            let docsBlocked = false;
            let missingCount = 0;
            if (step === 3) {
              const docReqs = window.DOC_REQUIREMENTS || DOC_REQUIREMENTS || {};
              const docTypes = window.DOC_TYPES || DOC_TYPES || [];
              const docLevels = {};
              for (const it of (draft.items || [])) {
                const reqs = docReqs[it.productId] || {};
                for (const [docId, level] of Object.entries(reqs)) {
                  if (level === 'none') continue;
                  if (!docLevels[docId] || (level === 'required' && docLevels[docId] !== 'required')) docLevels[docId] = level;
                }
              }
              const requiredIds = docTypes.filter(d => docLevels[d.id] === 'required').map(d => d.id);
              const uploadedIds = (draft.docs || []).map(d => d.docId);
              missingCount = requiredIds.filter(id => !uploadedIds.includes(id)).length;
              docsBlocked = missingCount > 0;
            }
            const hasDraftItems = draft.items?.length > 0;
            return (
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 12 }}>
                <Button variant="ghost" disabled={step === 0} onClick={prev} icon="chevronLeft">Back</Button>

                <div style={{ fontSize: 11, color: docsBlocked ? 'var(--negative)' : 'var(--ink-3)', display: 'flex', alignItems: 'center', gap: 6 }}>
                  {docsBlocked && <><Icon name="alert" size={11} color="var(--negative)"/> อัปโหลดเอกสาร Required อีก {missingCount} รายการ · </>}
                  Step <span className="num" style={{ color: 'var(--ink-2)' }}>{step + 1}</span>&nbsp;of&nbsp;<span className="num">{WIZARD_STEPS.length}</span>
                </div>

                <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 4 }}>
                  {submitError && (
                    <div style={{ fontSize: 11, color: 'var(--negative)', display: 'flex', alignItems: 'center', gap: 4 }}>
                      <Icon name="alert" size={11} color="var(--negative)"/> {submitError}
                    </div>
                  )}
                  <div style={{ display: 'flex', gap: 8 }}>
                    {hasDraftItems && (
                      <Button variant="ghost" icon={submitting ? 'clock' : 'bookmark'} onClick={handleSaveDraft} disabled={submitting}>
                        Save as Draft
                      </Button>
                    )}
                    {step < WIZARD_STEPS.length - 1
                      ? <Button variant="primary" onClick={next} iconRight="chevron" disabled={docsBlocked}>Continue</Button>
                      : (
                        <Button variant="accent" icon={submitting ? 'clock' : 'check'} onClick={handleSubmit} disabled={submitting}>
                          {submitting ? 'กำลังสร้าง order…' : 'Submit order'}
                        </Button>
                      )
                    }
                  </div>
                </div>
              </div>
            );
          })()}
        </div>
      </div>
    </>
  );
};

// ---------- Step 1: Company ----------
const CompanyStep = ({ draft, setDraft }) => {
  const [q, setQ] = useState('');
  const isNew = draft.customerType === 'new';
  const companies = window.COMPANIES || COMPANIES || [];
  const filtered = companies.filter(c => !q || c.name.toLowerCase().includes(q.toLowerCase()) || (c.taxId || '').includes(q));

  const pick = (c) => {
    if (isNew) return;
    setDraft(d => ({ ...d, companyId: c.id, company: c, contact: { ...(window.CONTACTS || CONTACTS || {})[c.id] } }));
  };

  return (
    <div style={{ padding: '24px 28px' }}>
      <StepHeader n={2} label="Company" th="เลือกบริษัทลูกค้า" desc="ค้นหาจาก customer database หรือเพิ่มบริษัทใหม่"/>

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 18, marginTop: 18 }}>
        <Field label="ค้นหาลูกค้า / Tax ID">
          <div style={{ position: 'relative' }}>
            <span style={{ position: 'absolute', left: 9, top: '50%', transform: 'translateY(-50%)', color: isNew ? 'var(--line-3)' : 'var(--ink-3)' }}>
              <Icon name="search" size={13}/>
            </span>
            <input value={q} onChange={e => setQ(e.target.value)}
              disabled={isNew}
              placeholder="ชื่อบริษัท หรือเลขประจำตัวผู้เสียภาษี…"
              style={{ ...inputStyle, paddingLeft: 30, opacity: isNew ? 0.4 : 1, cursor: isNew ? 'not-allowed' : 'text' }}/>
          </div>
        </Field>
        <Field label="ประเภทลูกค้า">
          <Select value={draft.customerType} onChange={e => setDraft(d => ({ ...d, customerType: e.target.value, companyId: null, company: e.target.value === 'new' ? {} : null, contact: {} }))}>
            <option value="existing">Existing customer</option>
            <option value="new">New customer (สร้างใหม่)</option>
          </Select>
        </Field>
      </div>

      <div style={{ marginTop: 18, position: 'relative' }}>
        <div className="eyebrow" style={{ marginBottom: 8, color: isNew ? 'var(--ink-4)' : 'var(--ink-3)' }}>
          Customer matches · {filtered.length} results
        </div>
        <div style={{
          border: `1px solid ${isNew ? 'var(--line-2)' : 'var(--line)'}`,
          borderRadius: 3, maxHeight: 260, overflowY: 'auto',
          opacity: isNew ? 0.4 : 1, pointerEvents: isNew ? 'none' : 'auto',
        }}>
          {filtered.map((c, i) => {
            const sel = !isNew && draft.companyId === c.id;
            return (
              <div key={c.id} onClick={() => pick(c)} style={{
                padding: '10px 14px',
                borderBottom: i === filtered.length - 1 ? 'none' : '1px solid var(--line-2)',
                background: sel ? 'var(--bg-2)' : 'transparent', cursor: isNew ? 'default' : 'pointer',
                display: 'grid', gridTemplateColumns: '32px 1fr auto auto', gap: 12, alignItems: 'center',
              }} onMouseEnter={e => !sel && !isNew && (e.currentTarget.style.background = 'var(--bg-hover)')}
                 onMouseLeave={e => !sel && !isNew && (e.currentTarget.style.background = 'transparent')}>
                <Avatar name={c.name} size={28} square/>
                <div>
                  <div style={{ fontWeight: 500, fontSize: 13 }}>{c.name}</div>
                  <div style={{ fontSize: 11, color: 'var(--ink-3)' }}>{c.sector} · {c.province}</div>
                </div>
                <div className="num" style={{ fontSize: 11, color: 'var(--ink-3)' }}>{c.taxId}</div>
                <div style={{ width: 18, display: 'grid', placeItems: 'center' }}>
                  {sel ? <Icon name="check" size={14} color="var(--positive)"/> : null}
                </div>
              </div>
            );
          })}
        </div>
        {isNew && (
          <div style={{
            position: 'absolute', inset: 0, top: 24, display: 'flex', alignItems: 'center', justifyContent: 'center',
            borderRadius: 3, pointerEvents: 'none',
          }}>
            <div style={{ background: 'var(--panel)', border: '1px solid var(--line-2)', borderRadius: 3, padding: '6px 14px', fontSize: 12, color: 'var(--ink-3)', display: 'flex', alignItems: 'center', gap: 6 }}>
              <Icon name="lock" size={12}/>
              New customer — กรอกข้อมูลในขั้นตอนถัดไป
            </div>
          </div>
        )}
      </div>

      {!isNew && draft.company && (
        <div style={{ marginTop: 16, padding: 14, background: 'var(--bg-2)', borderRadius: 3, display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12 }}>
          <DefStack label="Company" value={draft.company.name}/>
          <DefStack label="Tax ID" value={<span className="num">{draft.company.taxId}</span>}/>
          <DefStack label="Sector" value={draft.company.sector}/>
          <DefStack label="Size" value={`${draft.company.size} emp.`}/>
        </div>
      )}
    </div>
  );
};

// ---------- Step 2: Products ----------
const ProductsStep = ({ draft, setDraft, tweaks }) => {
  const [allProducts, setAllProducts] = React.useState(PRODUCTS || []);

  React.useEffect(() => {
    window.apiFetch('/api/products')
      .then(r => r.ok ? r.json() : null)
      .then(d => { if (d) { window.PRODUCTS = d; setAllProducts(d); } })
      .catch(() => {});
  }, []);

  const visibleProducts = allProducts.filter(p => !tweaks.hiddenProducts?.includes(p.id) && (p.status || 'live') === 'live');
  const [activeProductId, setActiveProductId] = useState(() => {
    const preselectedId = draft.items[0]?.productId;
    if (preselectedId && visibleProducts.find(p => p.id === preselectedId)) return preselectedId;
    return visibleProducts[0]?.id;
  });
  // Once API products load, sync activeProductId to preselect if it wasn't found in the initial product list
  const [preselectedSynced, setPreselectedSynced] = React.useState(false);
  React.useEffect(() => {
    if (preselectedSynced) return;
    const preselectedId = draft.items[0]?.productId;
    if (preselectedId && allProducts.find(p => p.id === preselectedId)) {
      setActiveProductId(preselectedId);
      setPreselectedSynced(true);
    }
  }, [allProducts]);
  // If activeProductId is not in visibleProducts (e.g. was deleted), reset to first visible
  const safeActiveId = visibleProducts.find(p => p.id === activeProductId) ? activeProductId : visibleProducts[0]?.id;
  const activeProduct = allProducts.find(p => p.id === safeActiveId);

  const inCart = (productId, packageId) => draft.items.find(i => i.productId === productId && i.packageId === packageId);
  const addPkg = (productId, packageId) => {
    setDraft(d => {
      const existing = d.items.find(i => i.productId === productId && i.packageId === packageId);
      if (existing) return d;
      // Remove other packages of the same product
      const without = d.items.filter(i => i.productId !== productId);
      const prod = (window.PRODUCTS || PRODUCTS || []).find(p => p.id === productId);
      const pkg = prod?.packages?.find(p => p.id === packageId);
      if (!prod || !pkg) return d;
      return { ...d, items: [...without, { productId, packageId, qty: pkg.seats }] };
    });
  };
  const removePkg = (productId) => setDraft(d => ({ ...d, items: d.items.filter(i => i.productId !== productId) }));
  const setQty = (productId, qty) => setDraft(d => ({
    ...d, items: d.items.map(i => i.productId === productId ? { ...i, qty: Math.max(1, parseInt(qty) || 1) } : i)
  }));

  const pkgMonthlyPrice = (pkg) => pkg ? (pkg.billingPeriod === 'yearly' ? pkg.price / 12 : pkg.price) : 0;

  const monthly = draft.items.reduce((sum, it) => {
    const prod = (window.PRODUCTS || PRODUCTS || []).find(p => p.id === it.productId);
    const pkg = prod?.packages?.find(p => p.id === it.packageId);
    return sum + pkgMonthlyPrice(pkg) * it.qty;
  }, 0);

  return (
    <div style={{ padding: '24px 28px' }}>
      <StepHeader n={1} label="Products & packages" th="เลือก product + package ที่ลูกค้าต้องการสมัคร"
        desc="หนึ่ง order เพิ่มได้หลาย product — ราคา MRR คำนวณรวมในแถบด้านล่าง"/>

      <div style={{ display: 'grid', gridTemplateColumns: '200px 1fr', gap: 16, marginTop: 16 }}>
        {/* Product list */}
        <div style={{ background: 'var(--bg-2)', borderRadius: 3, padding: 6 }}>
          {visibleProducts.map(p => {
            const isActive = safeActiveId === p.id;
            const isInCart = draft.items.some(i => i.productId === p.id);
            return (
              <button key={p.id} onClick={() => setActiveProductId(p.id)} style={{
                width: '100%', padding: 10, display: 'flex', alignItems: 'center', gap: 10,
                background: isActive ? 'var(--panel)' : 'transparent',
                border: 'none', borderRadius: 3, cursor: 'pointer',
                fontFamily: 'Kanit, sans-serif',
                boxShadow: isActive ? 'var(--shadow-segment)' : 'none',
                marginBottom: 2,
              }}>
                <ProductGlyph productId={p.id} size={28}/>
                <div style={{ textAlign: 'left', flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 12, fontWeight: 500 }}>{p.name}</div>
                  <div style={{ fontSize: 10.5, color: 'var(--ink-3)' }}>SLA <span className="num">{p.slaDays}d</span></div>
                </div>
                {isInCart && <Icon name="check" size={12} color="var(--positive)"/>}
              </button>
            );
          })}
        </div>

        {/* Package cards */}
        <div>
          <div style={{ padding: '4px 4px 12px' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <ProductGlyph productId={activeProduct.id} size={32}/>
              <div>
                <div style={{ fontWeight: 600, fontSize: 15 }}>{activeProduct.name}</div>
                <div style={{ fontSize: 11.5, color: 'var(--ink-3)' }}>{activeProduct.nameTh} · SLA <span className="num">{activeProduct.slaDays}</span> วันทำการ</div>
              </div>
            </div>
          </div>

          <div style={{ display: 'grid', gridTemplateColumns: `repeat(${Math.min(activeProduct.packages.length, 3)}, 1fr)`, gap: 8 }}>
            {activeProduct.packages.map(pkg => {
              const selected = inCart(activeProduct.id, pkg.id);
              return (
                <div key={pkg.id} onClick={() => selected ? null : addPkg(activeProduct.id, pkg.id)} style={{
                  background: 'var(--panel)',
                  border: `${selected ? '2px' : '1px'} solid ${selected ? activeProduct.color : 'var(--line)'}`,
                  borderRadius: 4, padding: 14, cursor: 'pointer',
                  position: 'relative', transition: 'all 120ms',
                }} onMouseEnter={e => !selected && (e.currentTarget.style.borderColor = 'var(--ink)')}
                   onMouseLeave={e => !selected && (e.currentTarget.style.borderColor = 'var(--line)')}>
                  {selected && (
                    <div style={{ position: 'absolute', top: 8, right: 8, width: 18, height: 18, borderRadius: '50%', background: activeProduct.color, display: 'grid', placeItems: 'center' }}>
                      <Icon name="check" size={10} color="#fff"/>
                    </div>
                  )}
                  <div style={{ fontWeight: 500, fontSize: 13 }}>{pkg.name}</div>
                  <div className="num" style={{ marginTop: 8, fontSize: 20, fontWeight: 500, letterSpacing: '-0.02em' }}>
                    ฿{pkg.price.toLocaleString()}
                    <span style={{ fontSize: 11, color: 'var(--ink-3)', marginLeft: 3, fontWeight: 400 }}>/{activeProduct.unit}/{pkg.billingPeriod === 'yearly' ? 'yr' : 'mo'}</span>
                  </div>
                  {pkg.billingPeriod === 'yearly' && (
                    <div style={{ fontSize: 10.5, color: 'var(--ink-3)', marginTop: 2 }}>
                      ≈ ฿{Math.round(pkg.price / 12).toLocaleString()}/{activeProduct.unit}/mo
                    </div>
                  )}
                  <div style={{ marginTop: 10, paddingTop: 10, borderTop: '1px solid var(--line-2)' }}>
                    {pkg.highlights.map((h, i) => (
                      <div key={i} style={{ display: 'flex', alignItems: 'flex-start', gap: 6, fontSize: 11, color: 'var(--ink-2)', padding: '3px 0' }}>
                        <Icon name="check" size={10} color={activeProduct.color}/>
                        <span>{h}</span>
                      </div>
                    ))}
                  </div>
                </div>
              );
            })}
          </div>

          {/* Quantity field for selected */}
          {draft.items.find(i => i.productId === activeProduct.id) && (() => {
            const it = draft.items.find(i => i.productId === activeProduct.id);
            const pkg = activeProduct.packages.find(p => p.id === it.packageId);
            return (
              <div style={{ marginTop: 14, padding: 12, background: 'var(--bg-2)', borderRadius: 3, display: 'flex', alignItems: 'center', gap: 14 }}>
                <Field label={`จำนวน ${activeProduct.unit}`}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
                    <button onClick={() => setQty(activeProduct.id, it.qty - 1)} style={iconBtn}><Icon name="close" size={10}/></button>
                    <input type="number" value={it.qty} onChange={e => setQty(activeProduct.id, e.target.value)}
                      style={{ ...inputStyle, width: 90, textAlign: 'center', fontFamily: 'IBM Plex Mono', fontWeight: 500 }}/>
                    <button onClick={() => setQty(activeProduct.id, it.qty + 1)} style={iconBtn}><Icon name="plus" size={10}/></button>
                  </div>
                </Field>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 11, color: 'var(--ink-3)' }}>Subtotal · {pkg.name}</div>
                  <div className="num" style={{ fontSize: 18, fontWeight: 500 }}>{fmtBaht(pkg.price * it.qty)}<span style={{ fontSize: 11, color: 'var(--ink-3)', marginLeft: 3 }}>/{pkg.billingPeriod === 'yearly' ? 'yr' : 'mo'}</span></div>
                  {pkg.billingPeriod === 'yearly' && <div style={{ fontSize: 10.5, color: 'var(--ink-3)' }}>≈ {fmtBaht(pkgMonthlyPrice(pkg) * it.qty)}/mo MRR</div>}
                </div>
                <Button variant="ghost" size="sm" icon="close" onClick={() => removePkg(activeProduct.id)}>Remove</Button>
              </div>
            );
          })()}
        </div>
      </div>

      {/* Running cart summary */}
      <div style={{ marginTop: 18, padding: '12px 14px', background: 'var(--ink)', color: '#fff', borderRadius: 3, display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
          <Icon name="cart" size={14} color="#fff"/>
          <span style={{ fontSize: 12 }}>{draft.items.length} product{draft.items.length !== 1 ? 's' : ''} in order</span>
          <div style={{ display: 'flex', gap: 4 }}>
            {draft.items.map(it => {
              const p = (window.PRODUCTS || PRODUCTS || []).find(x => x.id === it.productId);
              if (!p) return null;
              return <span key={it.productId} style={{ width: 8, height: 8, borderRadius: '50%', background: p.color }}/>;
            })}
          </div>
        </div>
        <div>
          <span style={{ fontSize: 11, opacity: 0.7, marginRight: 8 }}>MONTHLY MRR</span>
          <span className="num" style={{ fontSize: 18, fontWeight: 500 }}>{fmtBaht(monthly)}</span>
        </div>
      </div>
    </div>
  );
};

const iconBtn = {
  width: 28, height: 28, padding: 0,
  background: 'var(--panel)', border: '1px solid var(--line)',
  borderRadius: 3, cursor: 'pointer', color: 'var(--ink-2)',
  display: 'grid', placeItems: 'center',
};

// ---------- Step 3: Contact ----------
const SECTORS = ['Manufacturing','Retail','Banking','Logistics','Hospitality','Healthcare','Agriculture','Trading','Technology','Government','Education','Other'];
const SIZES   = ['1–49','50–199','200–499','500–999','1,000+'];

const ContactStep = ({ draft, setDraft }) => {
  const isNew = draft.customerType === 'new';
  const upd  = (k, v) => setDraft(d => ({ ...d, contact: { ...d.contact, [k]: v } }));
  const updCo = (k, v) => setDraft(d => ({ ...d, company: { ...(d.company || {}), [k]: v } }));
  return (
    <div style={{ padding: '24px 28px' }}>
      <StepHeader n={3} label="Primary contact" th="ข้อมูลผู้ติดต่อหลัก"
        desc="ผู้ที่จะรับการประสานงานจากทีม Provisioning และ Customer Success"/>

      {/* ── Company info (new customer only) ─────────────────────────────── */}
      {isNew && (
        <div style={{ marginTop: 20, padding: '16px 20px', background: 'var(--bg-2)', borderRadius: 4, border: '1px solid var(--line)' }}>
          <div className="eyebrow" style={{ marginBottom: 14, display: 'flex', alignItems: 'center', gap: 6 }}>
            <Icon name="building" size={11}/>
            ข้อมูลบริษัทลูกค้าใหม่ · New company information
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
            <Field label="ชื่อบริษัท" required>
              <TextInput placeholder="บริษัท / ห้างหุ้นส่วน / องค์กร"
                value={draft.company?.name || ''}
                onChange={e => updCo('name', e.target.value)}/>
            </Field>
            <Field label="เลขประจำตัวผู้เสียภาษี (Tax ID)" required>
              <TextInput placeholder="13 หลัก"
                value={draft.company?.taxId || ''}
                onChange={e => updCo('taxId', e.target.value)}/>
            </Field>
            <Field label="ประเภทธุรกิจ (Sector)">
              <Select value={draft.company?.sector || ''} onChange={e => updCo('sector', e.target.value)}>
                <option value="">— เลือกประเภท —</option>
                {SECTORS.map(s => <option key={s} value={s}>{s}</option>)}
              </Select>
            </Field>
            <Field label="จังหวัด (Province)">
              <TextInput placeholder="กรุงเทพมหานคร / จังหวัด"
                value={draft.company?.province || ''}
                onChange={e => updCo('province', e.target.value)}/>
            </Field>
            <Field label="ขนาดองค์กร (Company size)">
              <Select value={draft.company?.size || ''} onChange={e => updCo('size', e.target.value)}>
                <option value="">— เลือกขนาด —</option>
                {SIZES.map(s => <option key={s} value={s}>{s} emp.</option>)}
              </Select>
            </Field>
          </div>
        </div>
      )}

      {isNew && (
        <div style={{ margin: '18px 0 0', borderTop: '1px solid var(--line-2)', paddingTop: 18 }}>
          <div className="eyebrow" style={{ marginBottom: 14, display: 'flex', alignItems: 'center', gap: 6 }}>
            <Icon name="user" size={11}/>
            ข้อมูลผู้ติดต่อหลัก · Primary contact
          </div>
        </div>
      )}

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16, marginTop: isNew ? 0 : 18 }}>
        <Field label="ชื่อ-นามสกุล" required>
          <TextInput value={draft.contact?.name || ''} onChange={e => upd('name', e.target.value)}/>
        </Field>
        <Field label="ตำแหน่ง" required>
          <TextInput value={draft.contact?.role || ''} onChange={e => upd('role', e.target.value)}/>
        </Field>
        <Field label="ประเภทผู้ติดต่อ · Contact type" required>
          <Select value={draft.contact?.contactType || 'Primary'} onChange={e => upd('contactType', e.target.value)}>
            <option value="Primary">Primary</option>
            <option value="Executive">Executive</option>
            <option value="Accounting">Accounting</option>
            <option value="Sales">Sales</option>
            <option value="Technical">Technical</option>
          </Select>
        </Field>
        <Field label="อีเมล" required hint="ใช้สำหรับส่งใบเสนอราคา และ activation link">
          <TextInput type="email" value={draft.contact?.email || ''} onChange={e => upd('email', e.target.value)}/>
        </Field>
        <Field label="เบอร์โทรที่ทำงาน">
          <TextInput value={draft.contact?.phone || ''} onChange={e => upd('phone', e.target.value)}/>
        </Field>
        <Field label="เบอร์มือถือ" required>
          <TextInput value={draft.contact?.mobile || ''} onChange={e => upd('mobile', e.target.value)}/>
        </Field>
      </div>

      {/* Additional contacts */}
      <div style={{ marginTop: 22 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 8 }}>
          <div>
            <h3 style={{ fontSize: 14, fontWeight: 500, margin: 0 }}>Additional contacts</h3>
            <div style={{ fontSize: 11, color: 'var(--ink-3)' }}>ผู้ติดต่อสำรองสำหรับ technical และ billing</div>
          </div>
          <Button variant="ghost" size="sm" icon="plus">Add contact</Button>
        </div>
        <div style={{ padding: '16px 20px', background: 'var(--bg-2)', borderRadius: 3, display: 'flex', alignItems: 'center', gap: 12, color: 'var(--ink-3)', fontSize: 12 }}>
          <Icon name="info" size={14}/>
          ยังไม่ได้เพิ่ม Additional contacts — สามารถเพิ่มภายหลังได้จากหน้า Order detail
        </div>
      </div>
    </div>
  );
};

// ---------- Step 4: Documents ----------

const DocRow = ({ label, en, hint, file, onUpload, onRemove, accept }) => {
  const inputRef = React.useRef(null);
  const handleChange = (e) => {
    const f = e.target.files?.[0];
    if (!f) return;
    const sizeMb = (f.size / 1024 / 1024).toFixed(1);
    const sizeLabel = f.size < 1024 * 1024 ? `${Math.round(f.size / 1024)} KB` : `${sizeMb} MB`;
    onUpload && onUpload({ name: f.name, size: sizeLabel, file: f });
    e.target.value = '';
  };
  return (
  <div style={{
    padding: 12, border: `1px ${file ? 'solid' : 'dashed'} ${file ? 'var(--positive)' : 'var(--line-3)'}`, borderRadius: 3,
    display: 'grid', gridTemplateColumns: '32px 1fr auto', gap: 12, alignItems: 'center',
    background: file ? '#f6fef6' : 'var(--panel)',
  }}>
    <input ref={inputRef} type="file" accept={accept || '.pdf,.jpg,.jpeg,.png,.xlsx'} style={{ display: 'none' }} onChange={handleChange}/>
    <div style={{ width: 32, height: 32, borderRadius: 3, background: file ? '#e6f7e6' : 'var(--bg-2)', display: 'grid', placeItems: 'center' }}>
      <Icon name={file ? 'fileCheck' : 'file'} size={15} color={file ? 'var(--positive)' : 'var(--ink-3)'}/>
    </div>
    <div>
      <div style={{ fontWeight: 500, fontSize: 12.5 }}>
        {label}
        {en && <span style={{ fontSize: 10.5, color: 'var(--ink-3)', marginLeft: 6, fontWeight: 400 }}>{en}</span>}
      </div>
      <div style={{ fontSize: 10.5, color: file ? 'var(--positive)' : 'var(--ink-3)', marginTop: 1 }}>
        {file ? `${file.name} · ${file.size}` : hint}
      </div>
    </div>
    <div style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
      <Button variant={file ? 'ghost' : 'secondary'} size="sm" icon={file ? 'refresh' : 'upload'} onClick={() => inputRef.current?.click()}>
        {file ? 'Replace' : 'Upload'}
      </Button>
      {file && onRemove && (
        <button onClick={onRemove} title="ลบไฟล์" style={{
          background: 'none', border: 'none', cursor: 'pointer', color: 'var(--ink-4)',
          display: 'grid', placeItems: 'center', padding: 4, borderRadius: 3,
        }}>
          <Icon name="close" size={11}/>
        </button>
      )}
    </div>
  </div>
  );
};

const DocsStep = ({ draft, setDraft }) => {
  const docTypes = window.DOC_TYPES || DOC_TYPES || [];
  const docReqs  = window.DOC_REQUIREMENTS || DOC_REQUIREMENTS || {};

  // Get uploaded file for a doc type id
  const getFile = (id) => (draft.docs || []).find(d => d.docId === id) || null;

  // Upload a file for a specific doc type
  const handleUpload = (docId) => (fileInfo) => {
    setDraft(d => {
      const rest = (d.docs || []).filter(x => x.docId !== docId);
      return { ...d, docs: [...rest, { ...fileInfo, docId }] };
    });
  };

  // Remove a file for a specific doc type
  const handleRemove = (docId) => () => {
    setDraft(d => ({ ...d, docs: (d.docs || []).filter(x => x.docId !== docId) }));
  };

  // Compute max level (required > optional > none) per doc across all selected products
  const docLevels = {};
  for (const it of (draft.items || [])) {
    const reqs = docReqs[it.productId] || {};
    for (const [docId, level] of Object.entries(reqs)) {
      if (level === 'none') continue;
      const cur = docLevels[docId];
      if (!cur || (level === 'required' && cur !== 'required')) docLevels[docId] = level;
    }
  }

  const requiredDocs = docTypes.filter(d => docLevels[d.id] === 'required');
  const optionalDocs = docTypes.filter(d => docLevels[d.id] === 'optional');

  return (
    <div style={{ padding: '24px 28px' }}>
      <StepHeader n={4} label="Documents" th="เอกสารแนบที่จำเป็น"
        desc="แนบเอกสารเพื่อตรวจสอบและขึ้นทะเบียนลูกค้า — รูปแบบไฟล์ PDF, JPG, PNG (สูงสุด 10 MB)"/>

      {requiredDocs.length === 0 && optionalDocs.length === 0 ? (
        <div style={{ marginTop: 18, padding: '16px 20px', background: 'var(--bg-2)', borderRadius: 3, fontSize: 12, color: 'var(--ink-4)', textAlign: 'center', border: '1px dashed var(--line-3)' }}>
          ไม่มีเอกสารที่กำหนดไว้สำหรับสินค้าที่เลือก
        </div>
      ) : (
        <>
          {requiredDocs.length > 0 && (
            <div style={{ marginTop: 18, marginBottom: 10 }}>
              <div className="eyebrow" style={{ fontSize: 10, color: 'var(--ink-3)', marginBottom: 8, letterSpacing: '.07em' }}>
                เอกสารที่จำเป็น · Required
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                {requiredDocs.map(d => (
                  <DocRow key={d.id} label={d.label} en={d.en} hint={d.desc || ''} file={getFile(d.id)}
                    onUpload={handleUpload(d.id)} onRemove={handleRemove(d.id)} accept={d.formats ? d.formats.replace(/·/g,',').replace(/ /g,'').toLowerCase().split(',').map(x=>'.'+x.trim()).join(',') : undefined}/>
                ))}
              </div>
            </div>
          )}

          {optionalDocs.length > 0 && (
            <div style={{ marginTop: 14 }}>
              <div className="eyebrow" style={{ fontSize: 10, color: 'var(--ink-3)', marginBottom: 8, letterSpacing: '.07em' }}>
                เอกสารเพิ่มเติม · Optional
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                {optionalDocs.map(d => (
                  <DocRow key={d.id} label={d.label} en={d.en} hint={d.desc || ''} file={getFile(d.id)}
                    onUpload={handleUpload(d.id)} onRemove={handleRemove(d.id)} accept={d.formats ? d.formats.replace(/·/g,',').replace(/ /g,'').toLowerCase().split(',').map(x=>'.'+x.trim()).join(',') : undefined}/>
                ))}
              </div>
            </div>
          )}
        </>
      )}

      <div style={{ marginTop: 16, padding: '10px 14px', background: '#f4f1e8', border: '1px solid #e4dec8', borderRadius: 3, display: 'flex', alignItems: 'flex-start', gap: 10, fontSize: 11.5, color: 'var(--ink-2)' }}>
        <Icon name="shield" size={14} color="var(--ink-2)"/>
        <div>
          <div style={{ fontWeight: 500 }}>การจัดเก็บข้อมูล</div>
          <div>เอกสารถูกเก็บภายใต้ True Business KYC vault — เข้าถึงได้เฉพาะทีม Sales Ops และ Compliance ตาม PDPA</div>
        </div>
      </div>
    </div>
  );
};

// ---------- Step 5: Review ----------
const ReviewStep = ({ draft, setDraft, tweaks }) => {
  const products = draft.items.map(it => {
    const product = (window.PRODUCTS || PRODUCTS || []).find(p => p.id === it.productId);
    const pkg = product?.packages?.find(p => p.id === it.packageId);
    return { item: it, product, pkg };
  }).filter(x => x.product && x.pkg);
  const monthly = products.reduce((s, x) => {
    const perMonth = x.pkg.billingPeriod === 'yearly' ? x.pkg.price / 12 : x.pkg.price;
    return s + perMonth * x.item.qty;
  }, 0);
  const maxSla = products.length ? Math.max(...products.map(x => tweaks.slaOverride != null ? tweaks.slaOverride : x.product.slaDays)) : 0;

  return (
    <div style={{ padding: '24px 28px' }}>
      <StepHeader n={5} label="Review & submit" th="ตรวจสอบและส่งคำสั่งซื้อ"
        desc="ตรวจสอบรายละเอียดก่อนส่ง — หลังจากส่งจะเข้าสู่ขั้นตอน Pending approval หาก MRR เกินเพดานอำนาจ"/>

      <div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 14, marginTop: 18 }}>
        {/* Left: details */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
          <ReviewBlock title="Company" content={
            <>
              <DefStack label="Company" value={draft.company?.name || '—'}/>
              <DefStack label="Tax ID" value={<span className="num">{draft.company?.taxId || '—'}</span>}/>
              <DefStack label="Sector" value={draft.company?.sector || '—'}/>
              <DefStack label="Province" value={draft.company?.province || '—'}/>
            </>
          }/>
          <ReviewBlock title="Primary contact" content={
            <>
              <DefStack label="Name" value={draft.contact?.name || '—'}/>
              <DefStack label="Role" value={draft.contact?.role || '—'}/>
              <DefStack label="Email" value={draft.contact?.email || '—'}/>
              <DefStack label="Mobile" value={<span className="num">{draft.contact?.mobile || '—'}</span>}/>
            </>
          }/>
          <ReviewBlock title="Documents" content={
            <div style={{ gridColumn: '1 / -1', display: 'flex', flexDirection: 'column', gap: 6 }}>
              {(draft.docs || []).map((f, i) => (
                <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 12 }}>
                  <Icon name="fileCheck" size={12} color="var(--positive)"/>
                  <span style={{ flex: 1 }}>{f.name}</span>
                  <span className="num" style={{ fontSize: 11, color: 'var(--ink-3)' }}>{f.size}</span>
                </div>
              ))}
            </div>
          }/>
          <ReviewBlock title="หมายเหตุถึง Approver" content={
            <div style={{ gridColumn: '1 / -1' }}>
              <textarea
                value={draft.notes || ''}
                onChange={e => setDraft(d => ({ ...d, notes: e.target.value }))}
                placeholder="ข้อความถึง approver เช่น ลูกค้ามีความเร่งด่วน, เอกสารครบถ้วนแล้ว, ข้อมูลเพิ่มเติมที่ควรทราบ…"
                rows={3}
                style={{
                  width: '100%', boxSizing: 'border-box',
                  fontFamily: 'Kanit, sans-serif', fontSize: 12.5,
                  padding: '9px 12px', background: 'var(--panel)',
                  border: '1px solid var(--line)', borderRadius: 3,
                  color: 'var(--ink)', outline: 'none', resize: 'vertical',
                  lineHeight: 1.6,
                }}
                onFocus={e => e.target.style.borderColor = 'var(--ink)'}
                onBlur={e  => e.target.style.borderColor = 'var(--line)'}
              />
              <div style={{ fontSize: 11, color: 'var(--ink-4)', marginTop: 4 }}>
                ข้อความนี้จะแสดงใน Approval inbox ของ approver
              </div>
            </div>
          }/>
          <ReviewBlock title="Contract terms" content={
            <>
              <DefStack label="Contract term" value={
                <select value={draft.contractMonths} onChange={e => setDraft(d => ({ ...d, contractMonths: parseInt(e.target.value) }))}
                  style={{ ...inputStyle, padding: '4px 6px', fontSize: 12, width: 'auto' }}>
                  <option value={12}>12 months</option>
                  <option value={24}>24 months</option>
                  <option value={36}>36 months</option>
                </select>
              }/>
              <DefStack label="Service start" value={
                <DatePicker
                  value={draft.startDate}
                  onChange={v => setDraft(d => ({ ...d, startDate: v }))}
                  recommended={new Date(Date.now() + (maxSla + 4) * 86400000)}
                  recommendedLabel={`ส่งมอบตาม SLA ${maxSla} วันทำการ`}
                  asapLabel="เริ่มใช้งานทันทีตาม SLA"/>
              }/>
              <DefStack label="Estimated handover" value={
                <span className="num">{fmtDate(new Date(Date.now() + (maxSla + 4) * 86400000))}</span>
              }/>
              <DefStack label="Est. provisioning SLA" value={<span className="num">{maxSla} วันทำการ</span>}/>
            </>
          }/>
        </div>

        {/* Right: pricing summary */}
        <div style={{
          background: 'var(--ink)', color: '#fff', borderRadius: 4, padding: 20,
          alignSelf: 'flex-start', position: 'sticky', top: 76,
        }}>
          <div style={{ fontSize: 10.5, color: '#d97b2e', textTransform: 'uppercase', letterSpacing: '0.08em', fontWeight: 500, marginBottom: 12 }}>Order summary</div>

          <div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginBottom: 14 }}>
            {products.map(({ item, product, pkg }, i) => (
              <div key={i} style={{ display: 'flex', gap: 10, alignItems: 'flex-start' }}>
                <div style={{ width: 6, alignSelf: 'stretch', borderRadius: 2, background: product.color, flexShrink: 0 }}/>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 12, fontWeight: 500 }}>{product.name}</div>
                  <div style={{ fontSize: 10.5, color: 'rgba(255,255,255,0.55)' }}>{pkg.name} · <span className="num">{item.qty}</span> {product.unit}{item.qty > 1 ? 's' : ''}</div>
                </div>
                <div>
                  <div className="num" style={{ fontSize: 12, fontWeight: 500 }}>{fmtBaht(pkg.price * item.qty)}<span style={{ fontSize: 10, fontWeight: 400, opacity: 0.65, marginLeft: 2 }}>/{pkg.billingPeriod === 'yearly' ? 'yr' : 'mo'}</span></div>
                  {pkg.billingPeriod === 'yearly' && <div className="num" style={{ fontSize: 10, opacity: 0.55 }}>≈{fmtBaht(Math.round(pkg.price/12)*item.qty)}/mo</div>}
                </div>
              </div>
            ))}
          </div>

          <div style={{ borderTop: '1px solid #2a2d35', paddingTop: 12 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 11.5, color: 'rgba(255,255,255,0.65)', padding: '3px 0' }}>
              <span>Subtotal</span><span className="num">{fmtBaht(monthly)}</span>
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 11.5, color: 'rgba(255,255,255,0.65)', padding: '3px 0' }}>
              <span>VAT 7%</span><span className="num">{fmtBaht(monthly * 0.07)}</span>
            </div>
          </div>

          <div style={{ borderTop: '1px solid #2a2d35', marginTop: 8, paddingTop: 12, display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
            <div>
              <div style={{ fontSize: 10, color: '#d97b2e', textTransform: 'uppercase', letterSpacing: '0.08em' }}>Total MRR</div>
              <div style={{ fontSize: 10, color: 'rgba(255,255,255,0.55)' }}>{draft.contractMonths} mo contract</div>
            </div>
            <div className="num" style={{ fontSize: 24, fontWeight: 500, letterSpacing: '-0.02em' }}>{fmtBaht(monthly * 1.07)}</div>
          </div>

          <div style={{ marginTop: 14, padding: 10, background: '#22252d', borderRadius: 3, fontSize: 11, color: 'rgba(255,255,255,0.75)' }}>
            <div style={{ fontSize: 10, color: '#d97b2e', textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: 4 }}>Total contract value</div>
            <span className="num" style={{ fontSize: 15, fontWeight: 500, color: '#fff' }}>{fmtBaht(monthly * 1.07 * draft.contractMonths)}</span>
          </div>
        </div>
      </div>
    </div>
  );
};

// ---------- Step helpers ----------
const StepHeader = ({ n, label, th, desc }) => (
  <div>
    <div className="eyebrow">Step {n} of 5</div>
    <h2 style={{ fontSize: 18, fontWeight: 500, letterSpacing: '-0.01em', margin: '4px 0 2px' }}>
      {label} <span style={{ fontSize: 14, color: 'var(--ink-3)', fontWeight: 400, marginLeft: 6 }}>{th}</span>
    </h2>
    {desc && <div style={{ fontSize: 12, color: 'var(--ink-3)' }}>{desc}</div>}
  </div>
);

const ReviewBlock = ({ title, content }) => (
  <div style={{ background: 'var(--bg-2)', borderRadius: 3, padding: 14 }}>
    <div className="eyebrow" style={{ marginBottom: 8 }}>{title}</div>
    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>{content}</div>
  </div>
);

const DefStack = ({ label, value }) => (
  <div>
    <div style={{ fontSize: 10.5, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>{label}</div>
    <div style={{ fontSize: 12.5, color: 'var(--ink)', marginTop: 2 }}>{value}</div>
  </div>
);

Object.assign(window, { CreateOrderView });
