// Provisioning — orders that have been approved and are being provisioned

const PROV_STATUS_IDS = ['approved', 'provisioning'];

// ─── Helpers ─────────────────────────────────────────────────────────────────

const fmtProvDate = (d) => {
  if (!d) return '—';
  const dt = d instanceof Date ? d : new Date(d);
  return dt.toLocaleDateString('th-TH', { day: 'numeric', month: 'short', year: '2-digit' });
};

const fmtMRR = (n) => n >= 1000000 ? `฿${(n/1000000).toFixed(1)}M` : n >= 1000 ? `฿${(n/1000).toFixed(0)}K` : `฿${n}`;

// Days since order was approved (using createdAt as proxy if no approvedAt)
const daysSince = (dateVal) => {
  if (!dateVal) return null;
  const d = dateVal instanceof Date ? dateVal : new Date(dateVal);
  return Math.floor((Date.now() - d.getTime()) / 86400000);
};

// ─── Status badge ─────────────────────────────────────────────────────────────
const ProvStatusBadge = ({ statusId }) => {
  const cfg = {
    approved:     { label: 'Approved',     bg: '#ecfdf5', color: '#16a34a' },
    provisioning: { label: 'Provisioning', bg: '#eff6ff', color: '#2563eb' },
  }[statusId] || { label: statusId, bg: 'var(--bg-2)', color: 'var(--ink-3)' };
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 4,
      padding: '2px 8px', background: cfg.bg, color: cfg.color,
      borderRadius: 3, fontSize: 11, fontWeight: 600,
    }}>
      <span style={{ width: 5, height: 5, borderRadius: '50%', background: cfg.color }}/>
      {cfg.label}
    </span>
  );
};

// ─── Helper: get merged steps for an order (from per-product config) ──────────
// productProvSteps: { [productId]: step[] }
// falls back to global PROVISIONING_STEPS if no config found
const getOrderSteps = (order, productProvSteps) => {
  const productIds = [...new Set((order.items || []).map(it => it.productId).filter(Boolean))];
  if (!productIds.length) return { flat: [], byProduct: {} };

  const byProduct = {};
  for (const pid of productIds) {
    const s = (productProvSteps || {})[pid] || [];
    if (s.length) byProduct[pid] = s;
  }

  const flat = Object.values(byProduct).flat();
  return { flat, byProduct };
};

// Derive how many steps are "done" based on time + status (mock until real tracking)
const calcCompletedSteps = (order, steps) => {
  if (order.status?.id === 'approved') return 0;
  const daysElapsed = daysSince(order.createdAt) || 0;
  const totalDays   = steps.reduce((s, st) => s + (st.days || 2), 0);
  return Math.min(Math.floor((daysElapsed / Math.max(totalDays, 1)) * steps.length), steps.length);
};

// ─── Step key helper ──────────────────────────────────────────────────────────
const STEP_KEY = (step) => step.id ? `id:${step.id}` : `key:${step.label}`;

// ─── Step progress bar (list view) ───────────────────────────────────────────
const StepProgress = ({ order, productProvSteps, stepProgress = {} }) => {
  const { flat: steps } = getOrderSteps(order, productProvSteps);
  if (!steps.length) return <span style={{ fontSize: 11, color: 'var(--ink-4)' }}>—</span>;

  const doneCount = steps.filter(s => stepProgress[STEP_KEY(s)] === 'done').length;

  return (
    <div>
      <div style={{ display: 'flex', gap: 3, alignItems: 'center' }}>
        {steps.map((step, i) => {
          const st = stepProgress[STEP_KEY(step)] || 'pending';
          return (
            <div key={step.id || i} title={`${step.label}${step.owner ? ' · ' + step.owner : ''}`} style={{
              flex: 1, height: 5, borderRadius: 3,
              background: st === 'done' ? '#16a34a' : st === 'in_progress' ? '#2563eb' : 'var(--line-3)',
              transition: 'background 0.2s',
            }}/>
          );
        })}
      </div>
      <div style={{ fontSize: 10, color: 'var(--ink-4)', marginTop: 3 }}>
        {doneCount}/{steps.length} steps
        {order.status?.id === 'approved' ? ' · รอเริ่ม' : ''}
      </div>
    </div>
  );
};

// ─── Summary stats ────────────────────────────────────────────────────────────
const ProvStat = ({ label, value, sublabel, accent }) => (
  <div style={{
    background: 'var(--panel)', border: `1px solid ${accent ? accent + '44' : 'var(--line)'}`,
    borderRadius: 4, padding: '14px 18px',
    borderLeft: accent ? `3px solid ${accent}` : undefined,
  }}>
    <div className="eyebrow" style={{ fontSize: 9.5, marginBottom: 6 }}>{label}</div>
    <div className="num" style={{ fontSize: 24, fontWeight: 500, color: accent || 'var(--ink)' }}>{value}</div>
    <div style={{ fontSize: 11, color: 'var(--ink-3)', marginTop: 3 }}>{sublabel}</div>
  </div>
);

// ─── Step list (used in modal) ────────────────────────────────────────────────
const STEP_STATUS_NEXT  = { pending: 'in_progress', in_progress: 'done', done: 'pending' };
const STEP_STATUS_CFG   = {
  pending:     { bg: 'var(--bg-2)',  border: 'var(--line)',   label: 'รอดำเนินการ',    labelColor: 'var(--ink-4)',  iconBg: null,      iconColor: null    },
  in_progress: { bg: '#eff6ff',     border: '#bfdbfe',       label: 'กำลังดำเนินการ', labelColor: '#2563eb',       iconBg: '#2563eb', iconColor: '#fff'  },
  done:        { bg: '#f0fdf4',     border: '#bbf7d0',       label: 'เสร็จแล้ว',       labelColor: '#16a34a',       iconBg: '#16a34a', iconColor: '#fff'  },
};

const StepList = ({ steps, stepProgress = {}, onStepClick, canEdit = false }) => (
  <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
    {steps.map((step, i) => {
      const key    = STEP_KEY(step);
      const status = stepProgress[key] || 'pending';
      const cfg    = STEP_STATUS_CFG[status];
      const stepColor = step.color || '#6366f1';
      return (
        <div key={step.id || i} style={{
          display: 'flex', alignItems: 'center', gap: 12,
          padding: '10px 14px', borderRadius: 4,
          background: cfg.bg, border: `1px solid ${cfg.border}`,
          transition: 'background 0.15s, border-color 0.15s',
        }}>
          {/* Icon circle */}
          <div style={{
            width: 28, height: 28, borderRadius: '50%', flexShrink: 0,
            background: cfg.iconBg || (stepColor + '22'),
            border: `1.5px solid ${cfg.iconBg || (stepColor + '55')}`,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            {status === 'done'
              ? <Icon name="check" size={12} color="#fff"/>
              : <Icon name={step.icon || 'cog'} size={11} color={cfg.iconBg ? cfg.iconColor : stepColor}/>
            }
          </div>

          {/* Label + meta */}
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 12.5, fontWeight: status !== 'pending' ? 600 : 400, color: status === 'done' ? '#15803d' : status === 'in_progress' ? '#1d4ed8' : 'var(--ink)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
              {step.label}
              {step.labelTh && step.labelTh !== step.label && (
                <span style={{ fontSize: 11, fontWeight: 400, color: 'var(--ink-3)', marginLeft: 6 }}>({step.labelTh})</span>
              )}
            </div>
            <div style={{ fontSize: 11, color: 'var(--ink-4)', marginTop: 1 }}>
              {step.owner && <span>{step.owner}</span>}
              {step.owner && step.days && <span style={{ margin: '0 4px' }}>·</span>}
              {step.days && <span>{step.days} วัน</span>}
              {!step.owner && !step.days && '—'}
            </div>
          </div>

          {/* Status chip — clickable if canEdit */}
          {canEdit ? (
            <button
              onClick={() => onStepClick && onStepClick(step, status)}
              title="คลิกเพื่อเปลี่ยนสถานะ"
              style={{
                display: 'inline-flex', alignItems: 'center', gap: 4,
                padding: '4px 10px', borderRadius: 3, flexShrink: 0,
                fontSize: 11, fontWeight: status !== 'pending' ? 600 : 400,
                color: cfg.labelColor,
                background: status === 'done' ? '#dcfce7' : status === 'in_progress' ? '#dbeafe' : 'var(--bg-3)',
                border: `1px solid ${cfg.border}`,
                cursor: 'pointer', fontFamily: 'Kanit, sans-serif',
              }}
              onMouseEnter={e => e.currentTarget.style.opacity = '0.75'}
              onMouseLeave={e => e.currentTarget.style.opacity = '1'}
            >
              {status === 'done'        && <Icon name="check" size={10} color="#16a34a"/>}
              {status === 'in_progress' && <span style={{ width: 7, height: 7, borderRadius: '50%', background: '#2563eb', display: 'inline-block' }}/>}
              {cfg.label}
              <Icon name="chevron" size={8} color={cfg.labelColor}/>
            </button>
          ) : (
            <div style={{ fontSize: 10.5, fontWeight: status !== 'pending' ? 600 : 400, color: cfg.labelColor, display: 'flex', alignItems: 'center', gap: 4, flexShrink: 0 }}>
              {status === 'done'        && <Icon name="check" size={10} color="#16a34a"/>}
              {status === 'in_progress' && <span style={{ width: 7, height: 7, borderRadius: '50%', background: '#2563eb', display: 'inline-block' }}/>}
              {cfg.label}
            </div>
          )}
        </div>
      );
    })}
  </div>
);

// ─── Activity feed (mini — for modal) ────────────────────────────────────────
const PROV_ACT_CFG = {
  created:      { icon: 'plus',       color: 'var(--ink-3)' },
  submitted:    { icon: 'arrowRight', color: '#d97b2e' },
  approved:     { icon: 'check',      color: '#16a34a' },
  rejected:     { icon: 'close',      color: '#dc2626' },
  sent_back:    { icon: 'alert',      color: '#8b5cf6' },
  resubmitted:  { icon: 'arrowRight', color: '#d97b2e' },
  edited:       { icon: 'edit',       color: '#d97b2e' },
  provisioning: { icon: 'arrowRight', color: '#2563eb' },
  active:       { icon: 'check',      color: '#16a34a' },
};

const PROV_ACT_LABEL = {
  created:      'สร้างคำสั่งซื้อ',
  submitted:    'ส่งเพื่อพิจารณา',
  approved:     'อนุมัติแล้ว',
  rejected:     'ปฏิเสธ',
  sent_back:    'ส่งคืน requester',
  resubmitted:  'ส่งซ้ำ',
  edited:       'แก้ไขข้อมูล',
  provisioning: 'เริ่มดำเนินการ Provisioning',
  active:       'Provisioning สำเร็จ — Active',
};

const fmtActTime = (d) => {
  if (!d) return '';
  const dt = new Date(d);
  return dt.toLocaleDateString('th-TH', { day: 'numeric', month: 'short', year: '2-digit' }) +
    ' ' + dt.toLocaleTimeString('th-TH', { hour: '2-digit', minute: '2-digit' });
};

const ProvActivityFeed = ({ orderId }) => {
  const [acts, setActs] = React.useState(null);

  React.useEffect(() => {
    window.apiFetch(`/api/orders/${orderId}/activities`)
      .then(r => r.ok ? r.json() : [])
      .then(rows => setActs([...rows].sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt))))
      .catch(() => setActs([]));
  }, [orderId]);

  if (acts === null) return <div style={{ padding: '16px 0', textAlign: 'center', fontSize: 12, color: 'var(--ink-4)' }}>กำลังโหลด…</div>;
  if (!acts.length)  return <div style={{ padding: '16px 0', textAlign: 'center', fontSize: 12, color: 'var(--ink-4)' }}>ยังไม่มี activity</div>;

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 0 }}>
      {acts.map((ev, i) => {
        const cfg  = PROV_ACT_CFG[ev.action] || { icon: 'dot', color: 'var(--ink-3)' };
        const label = PROV_ACT_LABEL[ev.action] || ev.label || ev.action;
        const isLast = i === acts.length - 1;
        return (
          <div key={ev.id || i} style={{ display: 'flex', gap: 12, padding: '8px 0',
            borderBottom: isLast ? 'none' : '1px solid var(--line-2)' }}>
            {/* Icon */}
            <div style={{
              width: 26, height: 26, borderRadius: '50%', flexShrink: 0,
              background: cfg.color + '18', border: `1px solid ${cfg.color}44`,
              display: 'grid', placeItems: 'center',
            }}>
              <Icon name={cfg.icon} size={11} color={cfg.color}/>
            </div>
            {/* Content */}
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 12.5, fontWeight: 500, color: 'var(--ink)' }}>{label}</div>
              <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginTop: 2 }}>
                <span style={{ fontSize: 11, color: 'var(--ink-3)' }}>{ev.userName || 'System'}</span>
                {ev.userRole && <span style={{ fontSize: 11, color: 'var(--ink-4)' }}>· {ev.userRole}</span>}
              </div>
              {ev.note && (
                <div style={{ fontSize: 11.5, color: 'var(--ink-2)', marginTop: 3, fontStyle: 'italic',
                  background: 'var(--bg-2)', padding: '4px 8px', borderRadius: 3, borderLeft: `2px solid ${cfg.color}66` }}>
                  "{ev.note}"
                </div>
              )}
            </div>
            {/* Time */}
            <div style={{ fontSize: 10.5, color: 'var(--ink-4)', flexShrink: 0, textAlign: 'right', paddingTop: 2 }}>
              {fmtActTime(ev.createdAt)}
            </div>
          </div>
        );
      })}
    </div>
  );
};

// ─── Detail modal ─────────────────────────────────────────────────────────────
const ProvDetailModal = ({ order, onClose, onStatusChange, onStepChange, productProvSteps, onNavigateOneCall }) => {
  const [saving, setSaving] = React.useState(false);
  const [activeTab, setActiveTab] = React.useState('steps'); // 'steps' | 'activity'
  const [stepProgress, setStepProgress] = React.useState({});
  const [stepMetaMap, setStepMetaMap] = React.useState({});
  const { perms = {} } = React.useContext(window.PermCtx);
  const canProvisioning = perms['Manage provisioning'] === true || perms['Admin Setting'] === true;

  // Document review state
  const [docReviewOpen, setDocReviewOpen] = React.useState(false);
  const [docReviewStep, setDocReviewStep] = React.useState(null);
  const [docReviewDocs, setDocReviewDocs] = React.useState(null);
  const [docVerifiedMap, setDocVerifiedMap] = React.useState({});
  const [viewingDoc, setViewingDoc] = React.useState(null); // { id, filename, orderId }
  const [viewingDocBlobUrl, setViewingDocBlobUrl] = React.useState(null);

  React.useEffect(() => {
    if (!viewingDoc?.hasFile) { setViewingDocBlobUrl(null); return; }
    let url = null;
    window.apiFetch(`/api/orders/${viewingDoc.orderId}/documents/${viewingDoc.id}/file`)
      .then(r => r.blob()).then(b => { url = URL.createObjectURL(b); setViewingDocBlobUrl(url); })
      .catch(() => setViewingDocBlobUrl(null));
    return () => { if (url) URL.revokeObjectURL(url); };
  }, [viewingDoc]);

  const docTypesMap = React.useMemo(() => {
    const m = {};
    for (const dt of (window.DOC_TYPES || [])) m[dt.id] = dt;
    return m;
  }, []);

  // Load step progress for this order
  React.useEffect(() => {
    window.apiFetch(`/api/orders/${order.id}/prov-progress`)
      .then(r => r.ok ? r.json() : [])
      .then(rows => {
        const m = {};
        const mm = {};
        for (const r of rows) {
          const k = r.stepId ? `id:${r.stepId}` : (r.stepKey ? `key:${r.stepKey}` : null);
          if (k) { m[k] = r.status; mm[k] = r.meta || {}; }
        }
        setStepProgress(m);
        setStepMetaMap(mm);
      })
      .catch(() => {});
  }, [order.id]);

  const openDocReview = (step) => {
    setDocReviewStep(step);
    setDocReviewOpen(true);
    setDocReviewDocs(null);
    window.apiFetch(`/api/orders/${order.id}/documents`)
      .then(r => r.ok ? r.json() : [])
      .then(rows => {
        setDocReviewDocs(rows);
        const vm = {};
        for (const d of rows) vm[d.id] = !!d.verified;
        setDocVerifiedMap(vm);
      })
      .catch(() => setDocReviewDocs([]));
  };

  const handleVerifyDoc = async (docId) => {
    const currentVerified = !!docVerifiedMap[docId];
    const newVal = !currentVerified;
    const newMap = { ...docVerifiedMap, [docId]: newVal };
    setDocVerifiedMap(newMap);

    await window.apiFetch(`/api/orders/${order.id}/documents/${docId}/verify`, {
      method: 'PATCH',
      body: JSON.stringify({ verified: newVal }),
    }).catch(() => {
      setDocVerifiedMap(prev => ({ ...prev, [docId]: currentVerified }));
    });

    // Auto-complete doc review step when all docs verified
    const allVerified = docReviewDocs && docReviewDocs.length > 0 &&
      docReviewDocs.every(d => newMap[d.id]);
    if (allVerified && docReviewStep) {
      const key = STEP_KEY(docReviewStep);
      setStepProgress(prev => ({ ...prev, [key]: 'done' }));
      onStepChange && onStepChange(order.id, key, 'done');
      window.apiFetch(`/api/orders/${order.id}/prov-progress`, {
        method: 'PATCH',
        body: JSON.stringify({
          ...(docReviewStep.id ? { stepId: docReviewStep.id } : { stepKey: docReviewStep.label }),
          status: 'done',
        }),
      }).catch(() => {});
    }
  };

  const handleStepClick = (step, currentStatus) => {
    if (!canProvisioning || order.status?.id !== 'provisioning') return;
    // Document Review step — show doc review panel
    if ((step.label || '').toLowerCase().includes('document review') || (step.labelTh || '').toLowerCase().includes('document review')) {
      openDocReview(step);
      return;
    }
    // If this is the "Create Order One Call" step
    if ((step.label || '').toLowerCase().includes('one call') || (step.labelTh || '').includes('One Call')) {
      const key = STEP_KEY(step);
      const stepMeta = stepMetaMap[key] || {};
      // If already linked to a One Call order, navigate to view it
      if (stepMeta.oneCallOrderId) {
        onNavigateOneCall && onNavigateOneCall({ openOrderId: stepMeta.oneCallOrderId });
        return;
      }
      // Otherwise create new — set to in_progress if pending
      if (currentStatus === 'pending') {
        setStepProgress(prev => ({ ...prev, [key]: 'in_progress' }));
        onStepChange && onStepChange(order.id, key, 'in_progress');
        window.apiFetch(`/api/orders/${order.id}/prov-progress`, {
          method: 'PATCH',
          body: JSON.stringify({
            ...(step.id ? { stepId: step.id } : { stepKey: step.label }),
            status: 'in_progress',
          }),
        }).catch(() => {
          setStepProgress(prev => ({ ...prev, [key]: currentStatus }));
          onStepChange && onStepChange(order.id, key, currentStatus);
        });
      }
      onNavigateOneCall && onNavigateOneCall({
        companyId: order.company?.id, company: order.company,
        fromSolOrder: { orderId: order.id, ...(step.id ? { stepId: step.id } : { stepKey: step.label }) },
      });
      return;
    }
    const nextStatus = STEP_STATUS_NEXT[currentStatus] || 'in_progress';
    const key = STEP_KEY(step);
    // Optimistic update — local modal state
    setStepProgress(prev => ({ ...prev, [key]: nextStatus }));
    // Also notify parent so list view updates immediately
    onStepChange && onStepChange(order.id, key, nextStatus);
    window.apiFetch(`/api/orders/${order.id}/prov-progress`, {
      method: 'PATCH',
      body: JSON.stringify({
        ...(step.id ? { stepId: step.id } : { stepKey: step.label }),
        status: nextStatus,
      }),
    }).catch(() => {
      // Revert on error (both local + parent)
      setStepProgress(prev => ({ ...prev, [key]: currentStatus }));
      onStepChange && onStepChange(order.id, key, currentStatus);
    });
  };
  const users = window.USERS || [];
  const owner = users.find(u => u.id === order.owner);
  const prods = window.PRODUCTS || [];
  const products = (order.items || []).filter(Boolean).map(it => ({
    item: it,
    product: prods.find(p => p.id === it.productId),
    pkg: prods.find(p => p.id === it.productId)?.packages?.find(pk => pk.id === it.packageId),
  })).filter(x => x.product && x.product.name);

  // Per-product steps from config
  const { flat: allSteps, byProduct } = getOrderSteps(order, productProvSteps);
  const hasPerProductSteps = Object.keys(byProduct).length > 0;

  // Computed: how many steps are actually done (from real progress)
  const doneCount = allSteps.filter(s => stepProgress[STEP_KEY(s)] === 'done').length;
  const allStepsDone = allSteps.length > 0 && doneCount === allSteps.length;

  const handleChangeStatus = async (newStatusId) => {
    setSaving(true);
    try {
      const r = await window.apiFetch(`/api/orders/${order.id}/status`, {
        method: 'PATCH',
        body: JSON.stringify({ status: newStatusId }),
      });
      if (r.ok) {
        const updated = await window.apiFetch('/api/init').then(res => res.ok ? res.json() : null);
        if (updated?.orders) window.ORDERS = updated.orders;
        onStatusChange && onStatusChange();
        onClose();
      } else {
        const d = await r.json();
        alert(d.error || 'เกิดข้อผิดพลาด');
      }
    } catch { alert('เกิดข้อผิดพลาด'); }
    setSaving(false);
  };

  return (
    <>
    <div style={{
      position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.45)', zIndex: 1100,
      display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24,
    }} onClick={e => { if (e.target === e.currentTarget) onClose(); }}>
      <div style={{
        background: 'var(--panel)', borderRadius: 6, width: '100%', maxWidth: 700,
        border: '1px solid var(--line)', boxShadow: '0 8px 32px rgba(0,0,0,0.18)',
        display: 'flex', flexDirection: 'column', maxHeight: '90vh',
      }}>
        {/* Header */}
        <div style={{ padding: '18px 22px', borderBottom: '1px solid var(--line)', display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
          <div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 4 }}>
              <span className="num" style={{ fontSize: 18, fontWeight: 600 }}>{order.id}</span>
              <ProvStatusBadge statusId={order.status?.id}/>
            </div>
            <div style={{ fontSize: 13, color: 'var(--ink-2)' }}>{order.company?.name}</div>
            <div style={{ fontSize: 11.5, color: 'var(--ink-3)', marginTop: 2 }}>
              Owner: {owner?.name || '—'} · สร้างเมื่อ {fmtProvDate(order.createdAt)}
            </div>
          </div>
          <button onClick={onClose} style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--ink-3)', padding: 4 }}>
            <Icon name="close" size={16}/>
          </button>
        </div>

        {/* Tab bar */}
        <div style={{ display: 'flex', gap: 0, padding: '0 22px', borderBottom: '1px solid var(--line)', background: 'var(--bg-2)' }}>
          {[['steps','ขั้นตอน Provisioning'],['activity','Activity Log']].map(([tab, label]) => (
            <button key={tab} onClick={() => setActiveTab(tab)} style={{
              padding: '10px 16px', fontSize: 12.5, fontWeight: activeTab === tab ? 600 : 400,
              color: activeTab === tab ? 'var(--accent)' : 'var(--ink-3)',
              background: 'none', border: 'none', cursor: 'pointer',
              borderBottom: `2px solid ${activeTab === tab ? 'var(--accent)' : 'transparent'}`,
              fontFamily: 'Kanit, sans-serif', marginBottom: -1,
            }}>{label}</button>
          ))}
        </div>

        <div style={{ padding: '18px 22px', overflowY: 'auto', flex: 1, display: 'flex', flexDirection: 'column', gap: 20 }}>
          {/* Products (always shown) */}
          <div>
            <div style={{ fontSize: 11, fontWeight: 600, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 10 }}>สินค้า</div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {products.map(({ item: it, product, pkg }, i) => (
                <div key={i} style={{
                  display: 'flex', alignItems: 'center', gap: 12,
                  padding: '10px 14px', background: 'var(--bg-2)', borderRadius: 4,
                }}>
                  <ProductGlyph productId={it.productId} size={28}/>
                  <div style={{ flex: 1 }}>
                    <div style={{ fontWeight: 500, fontSize: 13 }}>{product.name}
                      <span style={{ color: 'var(--ink-3)', fontWeight: 400 }}> · {pkg?.name || '—'}</span>
                    </div>
                    <div style={{ fontSize: 11, color: 'var(--ink-3)' }}>
                      {it.qty} {product.unit} · ฿{(pkg?.price || it.unitPrice || 0).toLocaleString()}/mo
                    </div>
                  </div>
                  <div className="num" style={{ fontSize: 13, fontWeight: 600 }}>
                    ฿{((pkg?.price || it.unitPrice || 0) * it.qty).toLocaleString()}<span style={{ fontSize: 10, fontWeight: 400, color: 'var(--ink-3)' }}>/mo</span>
                  </div>
                </div>
              ))}
            </div>
          </div>

          {/* Activity tab */}
          {activeTab === 'activity' && (
            <ProvActivityFeed orderId={order.id}/>
          )}

          {/* Document review panel */}
          {activeTab === 'steps' && docReviewOpen && (
            <div style={{
              border: '1.5px solid #bfdbfe', borderRadius: 6,
              background: '#f8faff', overflow: 'hidden',
            }}>
              {/* Panel header */}
              <div style={{
                display: 'flex', alignItems: 'center', justifyContent: 'space-between',
                padding: '11px 16px',
                background: '#eff6ff', borderBottom: '1px solid #bfdbfe',
              }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                  <Icon name="file" size={13} color="#2563eb"/>
                  <span style={{ fontSize: 13, fontWeight: 600, color: '#1d4ed8' }}>Document Review</span>
                </div>
                <button
                  onClick={() => setDocReviewOpen(false)}
                  style={{
                    background: '#fff', border: '1px solid #bfdbfe', cursor: 'pointer',
                    color: '#1d4ed8', padding: '4px 10px', borderRadius: 4,
                    display: 'flex', alignItems: 'center', gap: 5, fontSize: 12, fontWeight: 500,
                    fontFamily: 'Kanit, sans-serif',
                  }}
                  onMouseEnter={e => e.currentTarget.style.background = '#dbeafe'}
                  onMouseLeave={e => e.currentTarget.style.background = '#fff'}
                >
                  <svg width="12" height="12" viewBox="0 0 16 16" fill="none" style={{ transform: 'rotate(180deg)' }}>
                    <path d="M6 4l4 4-4 4" stroke="#2563eb" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
                  </svg>
                  กลับไปขั้นตอน
                </button>
              </div>
              <div style={{ padding: '14px 16px' }}>

              {docReviewDocs === null ? (
                <div style={{ padding: '24px', textAlign: 'center', fontSize: 12.5, color: 'var(--ink-4)' }}>กำลังโหลดเอกสาร…</div>
              ) : docReviewDocs.length === 0 ? (
                <div style={{ padding: '24px', textAlign: 'center', background: 'var(--bg-2)', borderRadius: 4, fontSize: 12.5, color: 'var(--ink-3)' }}>
                  ไม่มีเอกสารแนบสำหรับ Order นี้
                </div>
              ) : (
                <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                  {(() => {
                    const verifiedCount = docReviewDocs.filter(d => docVerifiedMap[d.id]).length;
                    const allDone = verifiedCount === docReviewDocs.length;
                    return (
                      <>
                        <div style={{ fontSize: 11.5, color: allDone ? '#16a34a' : 'var(--ink-4)', fontWeight: allDone ? 600 : 400, marginBottom: 4 }}>
                          {allDone ? '✓ ตรวจสอบครบทุกเอกสารแล้ว — สถานะ Document Review จะถูก Update เป็น เสร็จแล้ว อัตโนมัติ' : `ตรวจสอบแล้ว ${verifiedCount}/${docReviewDocs.length} เอกสาร`}
                        </div>
                        {docReviewDocs.map(doc => {
                          const dt = docTypesMap[doc.doc_type_id] || {};
                          const isVerified = !!docVerifiedMap[doc.id];
                          const ext = (doc.filename || '').split('.').pop().toUpperCase();
                          return (
                            <div key={doc.id} style={{
                              display: 'flex', alignItems: 'center', gap: 12,
                              padding: '10px 14px', borderRadius: 4,
                              background: isVerified ? '#f0fdf4' : 'var(--bg-2)',
                              border: `1px solid ${isVerified ? '#bbf7d0' : 'var(--line)'}`,
                              transition: 'background 0.15s, border-color 0.15s',
                            }}>
                              {/* File icon */}
                              <div style={{
                                width: 32, height: 32, borderRadius: 3, flexShrink: 0,
                                background: isVerified ? '#dcfce7' : 'var(--line-3)',
                                display: 'flex', alignItems: 'center', justifyContent: 'center',
                                fontSize: 9, fontWeight: 700,
                                color: isVerified ? '#16a34a' : 'var(--ink-3)',
                              }}>
                                {ext || 'FILE'}
                              </div>
                              {/* Info */}
                              <div style={{ flex: 1, minWidth: 0 }}>
                                <div style={{ fontWeight: 500, fontSize: 12.5, color: 'var(--ink)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                                  {doc.filename}
                                </div>
                                <div style={{ fontSize: 11, color: 'var(--ink-3)', marginTop: 1 }}>
                                  {dt.label || doc.doc_type_id || 'เอกสารอื่น'}
                                  {doc.size && <span style={{ marginLeft: 6 }}>· {doc.size}</span>}
                                </div>
                              </div>
                              {/* Action buttons */}
                              <div style={{ display: 'flex', gap: 6, flexShrink: 0 }}>
                                <button
                                  onClick={() => setViewingDoc({ id: doc.id, filename: doc.filename, orderId: order.id, hasFile: !!doc.file_path })}
                                  style={{
                                    padding: '5px 12px', borderRadius: 3, cursor: 'pointer',
                                    fontSize: 12, fontWeight: 500, fontFamily: 'Kanit, sans-serif',
                                    background: 'var(--bg-3)', color: 'var(--ink-2)',
                                    border: '1px solid var(--line)',
                                    display: 'inline-flex', alignItems: 'center', gap: 5,
                                  }}
                                  onMouseEnter={e => e.currentTarget.style.opacity = '0.75'}
                                  onMouseLeave={e => e.currentTarget.style.opacity = '1'}
                                >
                                  <Icon name="eye" size={11} color="var(--ink-3)"/>
                                  View
                                </button>
                                <button
                                  onClick={() => handleVerifyDoc(doc.id)}
                                  style={{
                                    padding: '5px 14px', borderRadius: 3, cursor: 'pointer',
                                    fontSize: 12, fontWeight: 600,
                                    fontFamily: 'Kanit, sans-serif',
                                    background: isVerified ? '#16a34a' : 'var(--ink)',
                                    color: '#fff',
                                    border: 'none',
                                    display: 'inline-flex', alignItems: 'center', gap: 5,
                                    transition: 'background 0.15s',
                                  }}
                                  onMouseEnter={e => e.currentTarget.style.opacity = '0.8'}
                                  onMouseLeave={e => e.currentTarget.style.opacity = '1'}
                                >
                                  {isVerified && <Icon name="check" size={10} color="#fff"/>}
                                  {isVerified ? 'ถูกต้องแล้ว' : 'Check'}
                                </button>
                              </div>
                            </div>
                          );
                        })}
                      </>
                    );
                  })()}
                </div>
              )}
              </div>
            </div>
          )}

          {/* Provisioning steps tab */}
          {activeTab === 'steps' && !docReviewOpen && <div>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10 }}>
              <div style={{ fontSize: 11, fontWeight: 600, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>ขั้นตอน Provisioning</div>
              <div style={{ fontSize: 10.5, color: allStepsDone ? '#16a34a' : 'var(--ink-4)', fontWeight: allStepsDone ? 600 : 400 }}>
                {doneCount}/{allSteps.length} เสร็จแล้ว
                {allSteps.reduce((s, st) => s + (st.days || 0), 0) > 0 && ` · รวม ${allSteps.reduce((s, st) => s + (st.days || 0), 0)} วัน`}
              </div>
            </div>

            {allSteps.length === 0 ? (
              <div style={{ padding: '20px 14px', background: 'var(--bg-2)', borderRadius: 4, textAlign: 'center', fontSize: 12.5, color: 'var(--ink-3)' }}>
                ยังไม่ได้กำหนดขั้นตอน Provisioning สำหรับ product นี้<br/>
                <span style={{ fontSize: 11 }}>ตั้งค่าได้ที่ Settings → Provision setting</span>
              </div>
            ) : (
              <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
                {/* If multiple products, group by product */}
                {hasPerProductSteps && products.length > 1
                  ? products.map(({ item: it, product }) => {
                      const pSteps = byProduct[it.productId] || [];
                      if (!pSteps.length) return null;
                      return (
                        <div key={it.productId}>
                          {/* Product label */}
                          <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 6 }}>
                            <ProductGlyph productId={it.productId} size={16}/>
                            <span style={{ fontSize: 11.5, fontWeight: 600, color: product?.color }}>{product?.name}</span>
                          </div>
                          <StepList
                            steps={pSteps}
                            stepProgress={stepProgress}
                            onStepClick={handleStepClick}
                            canEdit={canProvisioning && order.status?.id === 'provisioning'}
                          />
                        </div>
                      );
                    })
                  : <StepList
                      steps={allSteps}
                      stepProgress={stepProgress}
                      onStepClick={handleStepClick}
                      canEdit={canProvisioning && order.status?.id === 'provisioning'}
                    />
                }
              </div>
            )}
          </div>}
        </div>

        {/* Footer actions */}
        <div style={{ padding: '14px 22px', borderTop: '1px solid var(--line)', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 10 }}>
          <div style={{ fontSize: 12, color: 'var(--ink-3)' }}>MRR: <span className="num" style={{ fontWeight: 600, color: 'var(--ink)' }}>฿{(order.monthly || 0).toLocaleString()}</span>/เดือน</div>
          <div style={{ display: 'flex', gap: 8 }}>
            <button onClick={onClose} style={{
              padding: '7px 16px', background: 'var(--bg-2)', border: '1px solid var(--line)',
              borderRadius: 4, cursor: 'pointer', fontSize: 13,
            }}>ปิด</button>
            {order.status?.id === 'approved' && canProvisioning && (
              <button onClick={() => handleChangeStatus('provisioning')} disabled={saving} style={{
                padding: '7px 16px', background: '#2563eb', color: '#fff',
                border: 'none', borderRadius: 4, cursor: 'pointer', fontSize: 13, fontWeight: 600,
                display: 'flex', alignItems: 'center', gap: 6, opacity: saving ? 0.7 : 1,
              }}>
                <Icon name="arrowRight" size={12} color="#fff"/>
                เริ่ม Provisioning
              </button>
            )}
            {order.status?.id === 'provisioning' && canProvisioning && (
              <button
                onClick={() => allStepsDone && handleChangeStatus('active')}
                disabled={saving || !allStepsDone}
                title={!allStepsDone ? `ต้องทำครบทุก step ก่อน (${doneCount}/${allSteps.length} เสร็จแล้ว)` : ''}
                style={{
                  padding: '7px 16px', background: allStepsDone ? '#16a34a' : 'var(--line-3)', color: allStepsDone ? '#fff' : 'var(--ink-4)',
                  border: 'none', borderRadius: 4, fontSize: 13, fontWeight: 600,
                  display: 'flex', alignItems: 'center', gap: 6,
                  opacity: saving ? 0.7 : 1,
                  cursor: allStepsDone ? 'pointer' : 'not-allowed',
                  transition: 'background 0.2s, color 0.2s',
                }}>
                <Icon name="check" size={12} color={allStepsDone ? '#fff' : 'var(--ink-4)'}/>
                Mark as Active
              </button>
            )}
          </div>
        </div>
      </div>
    </div>

    {/* File viewer overlay */}
    {viewingDoc && (
      <div style={{
        position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.7)', zIndex: 1200,
        display: 'flex', flexDirection: 'column', padding: 24,
      }} onClick={e => { if (e.target === e.currentTarget) setViewingDoc(null); }}>
        <div style={{
          background: 'var(--panel)', borderRadius: 6, flex: 1,
          display: 'flex', flexDirection: 'column', overflow: 'hidden',
          border: '1px solid var(--line)', boxShadow: '0 8px 40px rgba(0,0,0,0.3)',
        }}>
          {/* Viewer header */}
          <div style={{
            padding: '12px 18px', borderBottom: '1px solid var(--line)',
            display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12,
          }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <Icon name="file" size={14} color="var(--ink-3)"/>
              <span style={{ fontSize: 13, fontWeight: 500, color: 'var(--ink)' }}>{viewingDoc.filename}</span>
            </div>
            <button onClick={() => setViewingDoc(null)} style={{
              background: 'none', border: 'none', cursor: 'pointer', color: 'var(--ink-3)', padding: 4,
              display: 'flex', alignItems: 'center', gap: 5, fontSize: 12,
            }}>
              <Icon name="close" size={14}/>
              ปิด
            </button>
          </div>
          {/* Viewer — iframe when file exists, else placeholder */}
          {viewingDoc.hasFile ? (
            <iframe
              src={viewingDocBlobUrl || ''}
              style={{ flex: 1, border: 'none', width: '100%' }}
              title={viewingDoc.filename}
              
            />
          ) : (
            <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 12, color: 'var(--ink-3)' }}>
              <Icon name="file" size={40} color="var(--line-3)"/>
              <div style={{ fontSize: 14, fontWeight: 500, color: 'var(--ink-2)' }}>{viewingDoc.filename}</div>
              <div style={{ fontSize: 12.5, color: 'var(--ink-4)' }}>ไม่มีไฟล์จริงสำหรับเอกสารนี้ (อัปโหลดเฉพาะ metadata)</div>
            </div>
          )}
        </div>
      </div>
    )}
    </>
  );
};

// ─── Main list ────────────────────────────────────────────────────────────────
const ProvisioningView = ({ onNavigateOneCall }) => {
  const [selectedOrderId, setSelectedOrderId] = React.useState(null);
  const [refreshKey, setRefreshKey] = React.useState(0);
  const [filterStatus, setFilterStatus] = React.useState('all');
  const [search, setSearch] = React.useState('');
  // Per-product provisioning steps from Provision setting
  const [productProvSteps, setProductProvSteps] = React.useState({});
  // Step-level progress for all orders { [orderId]: { [STEP_KEY]: status } }
  const [provProgress, setProvProgress] = React.useState({});

  React.useEffect(() => {
    window.apiFetch('/api/product-prov-steps')
      .then(r => r.json())
      .then(data => {
        if (!Array.isArray(data)) return;
        const grouped = {};
        for (const s of data) {
          if (!grouped[s.productId]) grouped[s.productId] = [];
          grouped[s.productId].push(s);
        }
        for (const pid of Object.keys(grouped)) {
          grouped[pid].sort((a, b) => a.sortOrder - b.sortOrder);
        }
        setProductProvSteps(grouped);
      })
      .catch(() => {});

    window.apiFetch('/api/prov-progress')
      .then(r => r.ok ? r.json() : [])
      .then(data => {
        if (!Array.isArray(data)) return;
        const byOrder = {};
        for (const r of data) {
          if (!byOrder[r.orderId]) byOrder[r.orderId] = {};
          if (r.stepId)       byOrder[r.orderId][`id:${r.stepId}`]    = r.status;
          else if (r.stepKey) byOrder[r.orderId][`key:${r.stepKey}`]  = r.status;
        }
        setProvProgress(byOrder);
      })
      .catch(() => {});
  }, [refreshKey]);

  const allOrders = window.ORDERS || [];
  const prods     = window.PRODUCTS || [];
  const users     = window.USERS || [];

  const provOrders = React.useMemo(() => {
    return allOrders.filter(o => PROV_STATUS_IDS.includes(o.status?.id));
  }, [refreshKey]); // eslint-disable-line

  const filtered = React.useMemo(() => {
    return provOrders.filter(o => {
      if (filterStatus !== 'all' && o.status?.id !== filterStatus) return false;
      if (search) {
        const q = search.toLowerCase();
        return o.id.toLowerCase().includes(q)
          || o.company?.name?.toLowerCase().includes(q)
          || (o.items || []).some(it => prods.find(p => p.id === it.productId)?.name?.toLowerCase().includes(q));
      }
      return true;
    });
  }, [provOrders, filterStatus, search]);

  const selectedOrder = provOrders.find(o => o.id === selectedOrderId);

  // KPI counts
  const approvedCount     = provOrders.filter(o => o.status?.id === 'approved').length;
  const provisioningCount = provOrders.filter(o => o.status?.id === 'provisioning').length;
  const totalMRR          = provOrders.reduce((s, o) => s + (o.monthly || 0), 0);
  const overdueCount      = provOrders.filter(o => {
    const d = daysSince(o.createdAt) || 0;
    return d > 7 && o.status?.id === 'approved';
  }).length;

  const handleRefresh = () => setRefreshKey(k => k + 1);

  // Update a single step in provProgress without full reload
  const handleStepChange = (orderId, stepKey, status) => {
    setProvProgress(prev => ({
      ...prev,
      [orderId]: { ...(prev[orderId] || {}), [stepKey]: status },
    }));
  };

  return (
    <>
      {/* Breadcrumb + title */}
      <div className="eyebrow" style={{ marginBottom: 6 }}>Solutions · Provisioning</div>
      <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', marginBottom: 18, gap: 16 }}>
        <div>
          <h1 style={{ fontSize: 22, fontWeight: 500, letterSpacing: '-0.01em', margin: '0 0 4px' }}>Provisioning</h1>
          <div style={{ fontSize: 12, color: 'var(--ink-3)' }}>
            Order ที่อนุมัติแล้ว รอเริ่มหรือกำลังดำเนินการ Provisioning
          </div>
        </div>
      </div>

      {/* KPI strip */}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12, marginBottom: 18 }}>
        <ProvStat label="AWAITING START"     value={approvedCount}     sublabel="รออนุมัติ → เริ่ม Provisioning"     accent={approvedCount > 0 ? '#d97b2e' : undefined}/>
        <ProvStat label="IN PROVISIONING"    value={provisioningCount} sublabel="กำลังดำเนินการอยู่"               accent={provisioningCount > 0 ? '#2563eb' : undefined}/>
        <ProvStat label="OVERDUE (> 7 DAYS)" value={overdueCount}      sublabel="อนุมัติแล้วแต่ยังไม่เริ่ม"         accent={overdueCount > 0 ? '#dc2626' : undefined}/>
        <ProvStat label="TOTAL MRR"          value={fmtMRR(totalMRR)}  sublabel="รวมทุก Order ในขั้นตอนนี้"        accent="#16a34a"/>
      </div>

      {/* Filter bar */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 14 }}>
        <div style={{ position: 'relative', flex: '0 0 280px' }}>
          <input
            value={search} onChange={e => setSearch(e.target.value)}
            placeholder="ค้นหา Order, บริษัท, Product..."
            style={{
              width: '100%', padding: '7px 10px 7px 28px', fontSize: 12.5,
              border: '1px solid var(--line)', borderRadius: 4, background: 'var(--panel)',
              outline: 'none', color: 'var(--ink)', boxSizing: 'border-box',
            }}
          />
          <span style={{ position: 'absolute', left: 9, top: '50%', transform: 'translateY(-50%)', pointerEvents: 'none' }}>
            <Icon name="search" size={13} color="var(--ink-4)"/>
          </span>
        </div>
        {['all','approved','provisioning'].map(s => (
          <button key={s} onClick={() => setFilterStatus(s)} style={{
            padding: '6px 14px', fontSize: 12, borderRadius: 4, cursor: 'pointer', fontFamily: 'Kanit, sans-serif',
            background: filterStatus === s ? 'var(--ink)' : 'var(--bg-2)',
            color: filterStatus === s ? '#fff' : 'var(--ink-2)',
            border: `1px solid ${filterStatus === s ? 'var(--ink)' : 'var(--line)'}`,
            fontWeight: filterStatus === s ? 600 : 400,
          }}>
            {{ all: 'ทั้งหมด', approved: 'Approved', provisioning: 'Provisioning' }[s]}
            {s === 'all'
              ? ` (${provOrders.length})`
              : s === 'approved' ? ` (${approvedCount})` : ` (${provisioningCount})`}
          </button>
        ))}
      </div>

      {/* Table */}
      {filtered.length === 0 ? (
        <div style={{ background: 'var(--panel)', border: '1px solid var(--line)', borderRadius: 4, padding: '60px 24px', textAlign: 'center' }}>
          <div style={{ fontSize: 32, marginBottom: 12 }}>✅</div>
          <div style={{ fontSize: 15, fontWeight: 600, marginBottom: 6 }}>ไม่มี Order ในขั้นตอนนี้</div>
          <div style={{ fontSize: 12.5, color: 'var(--ink-3)' }}>Order ที่อนุมัติแล้วจะปรากฏที่นี่เมื่อพร้อม Provisioning</div>
        </div>
      ) : (
        <div style={{ background: 'var(--panel)', border: '1px solid var(--line)', borderRadius: 4, overflow: 'hidden' }}>
          <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12.5 }}>
            <thead>
              <tr style={{ background: 'var(--bg-2)' }}>
                {[
                  ['ORDER ID',   'left',  140],
                  ['COMPANY',    'left',  null],
                  ['PRODUCTS',   'left',  null],
                  ['OWNER',      'left',  120],
                  ['STATUS',     'left',  130],
                  ['STEPS',      'left',  160],
                  ['MRR',        'right', 100],
                  ['APPROVED',   'right', 100],
                  ['',           'right', 80],
                ].map(([lbl, align, w], i) => (
                  <th key={i} className="eyebrow" style={{
                    padding: '10px 12px', textAlign: align, fontWeight: 500,
                    borderBottom: '1px solid var(--line)', width: w || undefined,
                  }}>{lbl}</th>
                ))}
              </tr>
            </thead>
            <tbody>
              {filtered.map((order, i) => {
                const products = (order.items || [])
                  .map(it => prods.find(p => p.id === it.productId))
                  .filter(Boolean);
                const owner = users.find(u => u.id === order.owner);
                const days  = daysSince(order.createdAt) || 0;
                const isOverdue = days > 7 && order.status?.id === 'approved';

                return (
                  <tr key={order.id}
                    style={{ borderBottom: i === filtered.length - 1 ? 'none' : '1px solid var(--line-2)', cursor: 'pointer' }}
                    onClick={() => setSelectedOrderId(order.id)}
                    onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-hover)'}
                    onMouseLeave={e => e.currentTarget.style.background = ''}
                  >
                    {/* Order ID */}
                    <td className="num" style={{ padding: '12px 12px', fontWeight: 600 }}>
                      {order.id}
                      {isOverdue && (
                        <div style={{ display: 'flex', alignItems: 'center', gap: 3, marginTop: 2 }}>
                          <Icon name="alert" size={10} color="#dc2626"/>
                          <span style={{ fontSize: 10, color: '#dc2626' }}>เกิน {days} วัน</span>
                        </div>
                      )}
                    </td>

                    {/* Company */}
                    <td style={{ padding: '12px 12px' }}>
                      <div style={{ fontWeight: 500 }}>{order.company?.name}</div>
                      <div style={{ fontSize: 11, color: 'var(--ink-3)' }}>{order.company?.sector}</div>
                    </td>

                    {/* Products */}
                    <td style={{ padding: '12px 12px' }}>
                      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>
                        {products.map(p => (
                          <span key={p.id} style={{
                            padding: '2px 6px', background: p.color + '22',
                            color: p.color, borderRadius: 2, fontSize: 11, fontWeight: 500,
                          }}>{p.name}</span>
                        ))}
                      </div>
                    </td>

                    {/* Owner */}
                    <td style={{ padding: '12px 12px', color: 'var(--ink-2)' }}>
                      <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                        <div style={{
                          width: 22, height: 22, borderRadius: '50%', background: 'var(--accent)',
                          display: 'flex', alignItems: 'center', justifyContent: 'center',
                          fontSize: 9, fontWeight: 700, color: '#fff', flexShrink: 0,
                        }}>
                          {(owner?.name || '?').slice(0, 2).toUpperCase()}
                        </div>
                        <span style={{ fontSize: 12 }}>{owner?.name || '—'}</span>
                      </div>
                    </td>

                    {/* Status */}
                    <td style={{ padding: '12px 12px' }}>
                      <ProvStatusBadge statusId={order.status?.id}/>
                    </td>

                    {/* Step progress */}
                    <td style={{ padding: '12px 12px' }}>
                      <StepProgress order={order} productProvSteps={productProvSteps} stepProgress={provProgress[order.id] || {}}/>
                    </td>

                    {/* MRR */}
                    <td className="num" style={{ padding: '12px 12px', textAlign: 'right', fontWeight: 600 }}>
                      ฿{(order.monthly || 0).toLocaleString()}
                    </td>

                    {/* Approved date */}
                    <td style={{ padding: '12px 12px', textAlign: 'right', color: 'var(--ink-3)', fontSize: 12 }}>
                      {fmtProvDate(order.createdAt)}
                      <div style={{ fontSize: 10, color: isOverdue ? '#dc2626' : 'var(--ink-4)' }}>
                        {days} วันที่แล้ว
                      </div>
                    </td>

                    {/* Action */}
                    <td style={{ padding: '12px 12px', textAlign: 'right' }}>
                      <button
                        onClick={e => { e.stopPropagation(); setSelectedOrderId(order.id); }}
                        style={{
                          padding: '5px 12px', background: 'var(--ink)', color: '#fff',
                          border: 'none', borderRadius: 3, cursor: 'pointer', fontSize: 12, fontWeight: 500,
                          display: 'inline-flex', alignItems: 'center', gap: 5,
                        }}
                      >
                        ดูรายละเอียด <Icon name="chevron" size={10} color="#fff"/>
                      </button>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      )}

      {/* Detail modal */}
      {selectedOrder && (
        <ProvDetailModal
          order={selectedOrder}
          onClose={() => setSelectedOrderId(null)}
          onStatusChange={handleRefresh}
          onStepChange={handleStepChange}
          productProvSteps={productProvSteps}
          onNavigateOneCall={onNavigateOneCall}
        />
      )}
    </>
  );
};

Object.assign(window, { ProvisioningView });
