// Orders page — real data from Horoshop API
// Statuses: new(1), preparing(10), shipped(6)

// ── Supplier badge ─────────────────────────────────────────────────
function SupplierBadge({ status, supplierResponse }) {
  let label, color, bg;
  if (!status || status === 'pending' || status === 'reminded') {
    label = 'Немає відповіді'; color = 'var(--warning)'; bg = 'rgba(245,158,11,.13)';
  } else if (status === 'auto_confirmed') {
    label = 'В наявності'; color = 'var(--credit)'; bg = 'rgba(16,185,129,.13)';
  } else if (status === 'answered') {
    const r = (supplierResponse || '').toLowerCase();
    if (r.includes('закінчив') || r.includes('нема') || r.includes('немає') || r.includes('відсутн')) {
      label = supplierResponse || 'Закінчився'; color = 'var(--danger)'; bg = 'rgba(244,63,94,.13)';
    } else {
      label = supplierResponse || 'В наявності'; color = 'var(--credit)'; bg = 'rgba(16,185,129,.13)';
    }
  } else if (status === 'snoozed' || status === 'client_no_answer' || status === 'escalated') {
    label = 'Немає відповіді'; color = 'var(--warning)'; bg = 'rgba(245,158,11,.13)';
  } else {
    return null;
  }
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, height: 18, padding: '0 6px', borderRadius: 4, background: bg, color, fontSize: 11, fontWeight: 500, whiteSpace: 'nowrap' }}>
      {label}
    </span>
  );
}

const PAYMENT_TYPES = [
  { id: 15, label: 'Післяплата' },
  { id: 26, label: 'Банківська картка' },
  { id: 32, label: 'Plata by Mono' },
  { id: 29, label: 'Безготівковий без ПДВ' },
  { id: 27, label: 'USDT TRC20' },
];

function FilterBar({ view, onView, query, onQuery, statusFilters, onToggleStatus, onClearStatus, orders, onRefresh, kanbanCols, onKanbanCols }) {
  const [drop, setDrop]         = useState(false);
  const [dropCols, setDropCols] = useState(false);
  const counts = orders.reduce((a, o) => { a[o.status] = (a[o.status] || 0) + 1; return a; }, {});
  const allStatusKeys = Object.keys(STATUSES);
  const n = statusFilters.length;
  const filterLabel = n === 0 ? "Усі статуси" : n === 1 ? (STATUSES[statusFilters[0]]?.label || statusFilters[0]) : `${n} статуси`;

  const toggleCol = (key) => {
    const next = kanbanCols.includes(key) ? kanbanCols.filter(k => k !== key) : [...kanbanCols, key];
    if (next.length === 0) return;
    onKanbanCols(next);
  };

  return (
    <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "16px 24px", borderBottom: "1px solid var(--border-subtle)", flexWrap: "wrap", flexShrink: 0 }}>
      <div style={{ position: "relative", width: 280 }}>
        <Icon name="search" size={14} style={{ position: "absolute", left: 12, top: "50%", transform: "translateY(-50%)", color: "var(--fg-muted)" }}/>
        <input value={query} onChange={e => onQuery(e.target.value)} placeholder="Пошук за номером, клієнтом, телефоном…" style={{
          width: "100%", height: 32, boxSizing: "border-box", padding: "0 12px 0 34px",
          background: "var(--bg-panel)", color: "var(--fg-primary)",
          border: "1px solid var(--border-default)", borderRadius: 6, fontSize: 12, outline: "none", fontFamily: "inherit",
        }}/>
      </div>

      {/* Status filter — multi-select */}
      <div style={{ position: "relative" }}>
        <Button variant={n > 0 ? "primary" : "secondary"} size="sm" leftIcon="filter" onClick={() => { setDrop(d => !d); setDropCols(false); }}>
          {filterLabel}
        </Button>
        {drop && (
          <>
            <div onClick={() => setDrop(false)} style={{ position: "fixed", inset: 0, zIndex: 4 }}/>
            <div style={{ position: "absolute", top: "calc(100% + 4px)", left: 0, minWidth: 240, background: "var(--bg-raised)", border: "1px solid var(--border-default)", borderRadius: 8, padding: 4, boxShadow: "var(--shadow-1)", zIndex: 5 }}>
              {n > 0 && (
                <>
                  <button onClick={onClearStatus} style={{ display: "flex", alignItems: "center", gap: 8, width: "100%", padding: "7px 10px", border: 0, borderRadius: 6, background: "transparent", cursor: "pointer", fontFamily: "inherit", color: "var(--danger)", fontSize: 12 }}>
                    <Icon name="x" size={13}/>
                    Очистити фільтр ({n})
                  </button>
                  <div style={{ margin: "2px 6px", borderTop: "1px solid var(--border-subtle)" }}/>
                </>
              )}
              {allStatusKeys.map(s => {
                const on = statusFilters.includes(s);
                return (
                  <button key={s} onClick={() => onToggleStatus(s)} style={{
                    display: "flex", alignItems: "center", gap: 10, width: "100%", padding: "7px 10px",
                    border: 0, borderRadius: 6, background: on ? "var(--bg-active)" : "transparent",
                    cursor: "pointer", fontFamily: "inherit", transition: "background 100ms",
                  }}>
                    <div style={{ width: 16, height: 16, borderRadius: 4, flexShrink: 0, background: on ? "var(--accent)" : "transparent", border: `1px solid ${on ? "var(--accent)" : "var(--border-strong)"}`, display: "flex", alignItems: "center", justifyContent: "center" }}>
                      {on && <Icon name="check" size={11} color="#fff"/>}
                    </div>
                    <StatusChip status={s}/>
                    <span style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--fg-muted)", marginLeft: "auto" }}>{counts[s] || 0}</span>
                  </button>
                );
              })}
            </div>
          </>
        )}
      </div>
      <div style={{ flex: 1 }}/>

      {/* Kanban column picker */}
      {view === "kanban" && (
        <div style={{ position: "relative" }}>
          <Button variant="secondary" size="sm" leftIcon="columns-3" onClick={() => { setDropCols(d => !d); setDrop(false); }}>
            Колонки ({kanbanCols.length}/{allStatusKeys.length})
          </Button>
          {dropCols && (
            <>
              <div onClick={() => setDropCols(false)} style={{ position: "fixed", inset: 0, zIndex: 4 }}/>
              <div style={{ position: "absolute", top: "calc(100% + 4px)", right: 0, minWidth: 240, background: "var(--bg-raised)", border: "1px solid var(--border-default)", borderRadius: 8, padding: 4, boxShadow: "var(--shadow-1)", zIndex: 5 }}>
                {allStatusKeys.map(s => {
                  const on = kanbanCols.includes(s);
                  return (
                    <button key={s} onClick={() => toggleCol(s)} style={{ display: "flex", alignItems: "center", gap: 10, width: "100%", padding: "7px 10px", border: 0, borderRadius: 6, background: "transparent", cursor: "pointer", fontFamily: "inherit" }}>
                      <div style={{ width: 16, height: 16, borderRadius: 4, flexShrink: 0, background: on ? "var(--accent)" : "transparent", border: `1px solid ${on ? "var(--accent)" : "var(--border-strong)"}`, display: "flex", alignItems: "center", justifyContent: "center" }}>
                        {on && <Icon name="check" size={11} color="#fff"/>}
                      </div>
                      <StatusChip status={s}/>
                      <span style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--fg-muted)", marginLeft: "auto" }}>{counts[s] || 0}</span>
                    </button>
                  );
                })}
                <div style={{ padding: "6px 10px 2px", borderTop: "1px solid var(--border-subtle)", marginTop: 4, display: "flex", gap: 6 }}>
                  <button onClick={() => onKanbanCols(allStatusKeys)} style={{ flex: 1, padding: "5px 0", fontSize: 11, border: "1px solid var(--border-default)", borderRadius: 5, background: "transparent", color: "var(--fg-secondary)", cursor: "pointer", fontFamily: "inherit" }}>Всі</button>
                  <button onClick={() => onKanbanCols(allStatusKeys.filter(k => counts[k] > 0))} style={{ flex: 1, padding: "5px 0", fontSize: 11, border: "1px solid var(--border-default)", borderRadius: 5, background: "transparent", color: "var(--fg-secondary)", cursor: "pointer", fontFamily: "inherit" }}>З замовл.</button>
                </div>
              </div>
            </>
          )}
        </div>
      )}

      <Button variant="secondary" size="sm" leftIcon="refresh-cw" onClick={onRefresh}>Оновити</Button>

      <div style={{ display: "flex", background: "var(--bg-panel)", borderRadius: 6, border: "1px solid var(--border-default)", padding: 2 }}>
        <button onClick={() => onView("table")} title="Таблиця" style={{ width: 30, height: 26, border: 0, background: view === "table" ? "var(--bg-raised)" : "transparent", color: view === "table" ? "var(--fg-primary)" : "var(--fg-muted)", borderRadius: 4, cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center" }}>
          <Icon name="list" size={14}/>
        </button>
        <button onClick={() => onView("kanban")} title="Канбан" style={{ width: 30, height: 26, border: 0, background: view === "kanban" ? "var(--bg-raised)" : "transparent", color: view === "kanban" ? "var(--fg-primary)" : "var(--fg-muted)", borderRadius: 4, cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center" }}>
          <Icon name="layout-grid" size={14}/>
        </button>
      </div>
    </div>
  );
}

// ── Table column definitions (order = user preference) ────────────
const COLUMNS = [
  { key: 'id',       label: '№',            w: 64,  render: (o)     => `#${o.id}` },
  { key: 'client',   label: 'Клієнт',       w: 180, render: (o)     => o.client },
  { key: 'phone',    label: 'Телефон',      w: 160, render: (o)     => fmtPhone(o.phone) },
  { key: 'products', label: 'Товари',       w: 220, render: (o)     => o.products.join(' · ') || '—' },
  { key: 'address',  label: 'Адреса',       w: 200, render: (o)     => o.address || '—' },
  { key: 'total',    label: 'Сума',         w: 110, render: (o)     => fmtMoney(o.total) },
  { key: 'payment',  label: 'Оплата',       w: 110, render: (o)     => <PaidBadge payed={o.payed}/> },
  { key: 'supplier', label: 'Постачальник', w: 160, render: (o, sm) => { const s = sm[String(o.id)]; return s ? <SupplierBadge status={s.status} supplierResponse={s.supplierResponse}/> : null; } },
  { key: 'status',   label: 'Статус',       w: 190, render: (o)     => <StatusChip status={o.status}/> },
  { key: 'created',  label: 'Дата',         w: 120, render: (o)     => o.created },
];
const COL_KEYS  = COLUMNS.map(c => c.key);
const COL_DEF_W = Object.fromEntries(COLUMNS.map(c => [c.key, c.w]));

function OrderTable({ orders, onSelect, selectedId, supplierMap = {} }) {
  const [colOrder, setColOrder] = useState(() => {
    try { const s = localStorage.getItem('crm_col_order'); return s ? JSON.parse(s) : COL_KEYS; } catch { return COL_KEYS; }
  });
  const [colWidths, setColWidths] = useState(() => {
    try { const s = localStorage.getItem('crm_col_widths2'); return s ? JSON.parse(s) : COL_DEF_W; } catch { return COL_DEF_W; }
  });
  const [dragOver, setDragOver] = useState(null);
  const dragKey = useRef(null);

  const orderedCols = colOrder.map(k => COLUMNS.find(c => c.key === k)).filter(Boolean);
  const minW = colOrder.reduce((s, k) => s + (colWidths[k] || COL_DEF_W[k] || 80), 0) + 48;

  const cellSt = (col, extra = {}) => {
    const isLast = orderedCols[orderedCols.length - 1]?.key === col.key;
    return {
      ...(isLast ? { flex: 1, minWidth: colWidths[col.key] } : { width: colWidths[col.key], flexShrink: 0 }),
      overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', ...extra,
    };
  };

  const startResize = (e, key) => {
    e.preventDefault(); e.stopPropagation();
    const startX = e.clientX, startW = colWidths[key] || COL_DEF_W[key] || 80;
    const onMove = ev => setColWidths(w => ({ ...w, [key]: Math.max(50, startW + ev.clientX - startX) }));
    const onUp   = () => {
      document.removeEventListener('mousemove', onMove);
      document.removeEventListener('mouseup', onUp);
      setColWidths(w => { try { localStorage.setItem('crm_col_widths2', JSON.stringify(w)); } catch {} return w; });
    };
    document.addEventListener('mousemove', onMove);
    document.addEventListener('mouseup', onUp);
  };

  const handleDrop = (toKey) => {
    const fromKey = dragKey.current;
    setDragOver(null); dragKey.current = null;
    if (!fromKey || fromKey === toKey) return;
    const next = [...colOrder];
    next.splice(next.indexOf(fromKey), 1);
    next.splice(next.indexOf(toKey), 0, fromKey);
    setColOrder(next);
    try { localStorage.setItem('crm_col_order', JSON.stringify(next)); } catch {}
  };

  return (
    <div style={{ flex: 1, overflow: 'auto' }}>
      <div style={{ minWidth: minW }}>
        {/* Header */}
        <div style={{ display: 'flex', padding: '0 24px', borderBottom: '1px solid var(--border-subtle)', background: 'var(--bg-panel)', position: 'sticky', top: 0, zIndex: 1 }}>
          {orderedCols.map(col => (
            <div key={col.key}
              draggable
              onDragStart={() => { dragKey.current = col.key; }}
              onDragOver={e => { e.preventDefault(); setDragOver(col.key); }}
              onDragLeave={() => setDragOver(d => d === col.key ? null : d)}
              onDrop={() => handleDrop(col.key)}
              onDragEnd={() => { setDragOver(null); dragKey.current = null; }}
              style={{ ...cellSt(col), position: 'relative', height: 40, display: 'flex', alignItems: 'center', cursor: 'grab', userSelect: 'none',
                borderLeft: dragOver === col.key ? '2px solid var(--accent)' : '2px solid transparent',
                transition: 'border-color 80ms',
              }}>
              <span style={{ fontSize: 11, fontWeight: 500, letterSpacing: '0.04em', textTransform: 'uppercase', color: 'var(--fg-muted)', paddingLeft: 2 }}>{col.label}</span>
              {/* Visible resize handle */}
              <div
                draggable={false}
                onMouseDown={e => startResize(e, col.key)}
                onMouseEnter={e => e.currentTarget.firstChild.style.background = 'var(--accent)'}
                onMouseLeave={e => e.currentTarget.firstChild.style.background = 'var(--border-strong)'}
                style={{ position: 'absolute', right: 0, top: 0, bottom: 0, width: 10, cursor: 'col-resize', zIndex: 2, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                <div style={{ width: 2, height: 16, background: 'var(--border-strong)', borderRadius: 1, transition: 'background 100ms' }}/>
              </div>
            </div>
          ))}
        </div>

        {/* Rows */}
        {orders.length === 0 ? (
          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 10, padding: '64px 24px', color: 'var(--fg-muted)' }}>
            <Icon name="package" size={36} style={{ opacity: 0.2 }}/>
            <span style={{ fontSize: 13 }}>Замовлень не знайдено</span>
          </div>
        ) : orders.map(o => (
          <div key={`${o.id}-${o.status}`} onClick={() => onSelect(o)}
            style={{ display: 'flex', padding: '12px 24px', borderBottom: '1px solid var(--border-subtle)', alignItems: 'center', cursor: 'pointer', background: selectedId === o.id ? 'var(--bg-active)' : 'transparent', transition: 'background 120ms' }}
            onMouseEnter={e => { if (selectedId !== o.id) e.currentTarget.style.background = 'var(--bg-hover)'; }}
            onMouseLeave={e => { if (selectedId !== o.id) e.currentTarget.style.background = 'transparent'; }}>
            {orderedCols.map(col => (
              <span key={col.key} style={cellSt(col, {
                fontSize: ['id','phone','total','created'].includes(col.key) ? 12 : 13,
                fontFamily: ['id','phone','total'].includes(col.key) ? 'var(--font-mono)' : 'inherit',
                fontVariantNumeric: col.key === 'total' ? 'tabular-nums' : 'normal',
                color: col.key === 'id' || col.key === 'created' ? 'var(--fg-muted)' : col.key === 'total' ? 'var(--fg-primary)' : 'var(--fg-secondary)',
                fontWeight: col.key === 'total' ? 500 : 'inherit',
              })}>
                {col.render(o, supplierMap)}
              </span>
            ))}
          </div>
        ))}
      </div>
    </div>
  );
}

function OrderKanban({ orders, onSelect, visibleCols, supplierMap = {} }) {
  const cols = (visibleCols || Object.keys(STATUSES));
  return (
    <div style={{ flex: 1, overflow: "auto", padding: 20 }}>
      <div style={{ display: "flex", gap: 12, height: "100%", minWidth: "fit-content" }}>
        {cols.map(s => {
          const items = orders.filter(o => o.status === s);
          return (
            <div key={s} style={{ width: 300, display: "flex", flexDirection: "column", gap: 8, flexShrink: 0 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 8, padding: "0 4px 8px" }}>
                <StatusChip status={s}/>
                <span style={{ fontSize: 12, color: "var(--fg-muted)", fontFamily: "var(--font-mono)" }}>{items.length}</span>
              </div>
              {items.map(o => (
                <div key={o.id} onClick={() => onSelect(o)} style={{
                  background: "var(--bg-panel)", border: "1px solid var(--border-subtle)", borderRadius: 10,
                  padding: 14, display: "flex", flexDirection: "column", gap: 8, cursor: "pointer",
                  transition: "border-color 120ms",
                }}
                  onMouseEnter={e => e.currentTarget.style.borderColor = "var(--border-strong)"}
                  onMouseLeave={e => e.currentTarget.style.borderColor = "var(--border-subtle)"}>
                  <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
                    <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--fg-muted)" }}>#{o.id}</span>
                    <PaidBadge payed={o.payed}/>
                  </div>
                  <span style={{ fontSize: 13, fontWeight: 500, color: "var(--fg-primary)" }}>{o.client}</span>
                  <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--fg-secondary)" }}>{fmtPhone(o.phone)}</span>
                  <span style={{ fontSize: 12, color: "var(--fg-secondary)", lineHeight: 1.4 }}>{o.products.slice(0,2).join(" · ")}{o.products.length > 2 ? ` +${o.products.length - 2}` : ""}</span>
                  {o.address && (
                    <div style={{ display: "flex", gap: 6, alignItems: "flex-start", fontSize: 11, color: "var(--fg-muted)" }}>
                      <Icon name="map-pin" size={12} style={{ marginTop: 2, flexShrink: 0 }}/>
                      <span style={{ lineHeight: 1.35 }}>{o.address}</span>
                    </div>
                  )}
                  {(() => { const s = supplierMap[String(o.id)]; return s ? <SupplierBadge status={s.status} supplierResponse={s.supplierResponse}/> : null; })()}
                  <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", paddingTop: 8, borderTop: "1px solid var(--border-subtle)" }}>
                    <span style={{ fontSize: 11, color: "var(--fg-muted)" }}>{o.created}</span>
                    <span style={{ fontFamily: "var(--font-mono)", fontSize: 13, fontWeight: 600, color: "var(--fg-primary)" }}>{fmtMoney(o.total)}</span>
                  </div>
                </div>
              ))}
              {items.length === 0 && (
                <div style={{ padding: "16px 4px", fontSize: 12, color: "var(--fg-muted)", textAlign: "center", border: "1px dashed var(--border-subtle)", borderRadius: 8 }}>Порожньо</div>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}

const DELIVERY_TYPES = [
  { id: 34, key: 'warehouse', label: 'Відділення Нової Пошти' },
  { id: 35, key: 'courier',   label: "Кур'єр Нової Пошти" },
  { id: 36, key: 'postomat',  label: 'Поштомат Нової Пошти' },
  { id: 8,  key: 'pickup',    label: 'Самовивіз' },
];

function deriveDeliveryKey(deliveryLabel) {
  if (!deliveryLabel) return null;
  const dl = deliveryLabel.toLowerCase();
  if (dl.includes('поштомат')) return 'postomat';
  if (dl.includes("кур'єр") || dl.includes('courier')) return 'courier';
  if (dl.includes('відділення')) return 'warehouse';
  if (dl.includes('самовив')) return 'pickup';
  return null;
}

function DeliveryEditor({ order, onFieldChange, onDeliveryTypeSelect, onClose }) {
  const [deliveryTypeKey, setDeliveryTypeKey]         = useState(null);
  const [cityQuery, setCityQuery]                     = useState('');
  const [citySuggestions, setCitySuggestions]         = useState([]);
  const [selectedNPCity, setSelectedNPCity]           = useState(null);
  const [selectedHoroshopCity, setSelectedHoroshopCity] = useState(null);
  const [warehouseQuery, setWarehouseQuery]           = useState('');
  const [warehouseSuggestions, setWarehouseSuggestions] = useState([]);
  const [selectedWarehouse, setSelectedWarehouse]     = useState(null);
  const [streetQuery, setStreetQuery]                 = useState('');
  const [streetSuggestions, setStreetSuggestions]     = useState([]);
  const [selectedStreet, setSelectedStreet]           = useState(null);
  const [building, setBuilding]                       = useState('');
  const [flat, setFlat]                               = useState('');
  const [saving, setSaving]                           = useState(false);
  const [searchingCity, setSearchingCity]             = useState(false);
  const [searchingWarehouse, setSearchingWarehouse]   = useState(false);
  const [searchingStreet, setSearchingStreet]         = useState(false);
  const [loadingKyiv, setLoadingKyiv]                 = useState(false);
  const timerRef = useRef(null);

  const debounce = (fn, ms = 400) => {
    clearTimeout(timerRef.current);
    timerRef.current = setTimeout(fn, ms);
  };

  const handleCityQueryChange = (val) => {
    setCityQuery(val);
    setSelectedNPCity(null);
    setSelectedHoroshopCity(null);
    setCitySuggestions([]);
    setWarehouseQuery(''); setWarehouseSuggestions([]); setSelectedWarehouse(null);
    setStreetQuery(''); setStreetSuggestions([]); setSelectedStreet(null);
    if (val.length < 2) return;
    debounce(async () => {
      setSearchingCity(true);
      try {
        const results = await API.searchNPCities(val);
        setCitySuggestions(results);
      } catch {}
      setSearchingCity(false);
    });
  };

  const handleSelectNPCity = async (city) => {
    setSelectedNPCity(city);
    setCityQuery(city.Present || city.MainDescription);
    setCitySuggestions([]);
    setWarehouseQuery(''); setWarehouseSuggestions([]); setSelectedWarehouse(null);
    setStreetQuery(''); setStreetSuggestions([]); setSelectedStreet(null);
    // знаходимо Horoshop-місто
    try {
      const realOrderId = order.id + 16; // PAYMENT_ID_OFFSET
      const cities = await API.findHoroshopCities(city.MainDescription, realOrderId, order.userId);
      if (cities && cities.length > 0) setSelectedHoroshopCity(cities[0]);
    } catch {}
  };

  const handleWarehouseQueryChange = (val) => {
    setWarehouseQuery(val);
    setSelectedWarehouse(null);
    setWarehouseSuggestions([]);
    if (!selectedNPCity || val.length < 1) return;
    debounce(async () => {
      setSearchingWarehouse(true);
      try {
        const results = await API.searchNPWarehouses(selectedNPCity.MainDescription, val);
        setWarehouseSuggestions(results);
      } catch {}
      setSearchingWarehouse(false);
    });
  };

  const handleStreetQueryChange = (val) => {
    setStreetQuery(val);
    setSelectedStreet(null);
    setStreetSuggestions([]);
    if (!selectedNPCity || val.length < 1) return;
    debounce(async () => {
      setSearchingStreet(true);
      try {
        const results = await API.searchNPStreets(selectedNPCity.DeliveryCity, val);
        setStreetSuggestions(results);
      } catch {}
      setSearchingStreet(false);
    });
  };

  const handleDeliveryTypeClick = async (key) => {
    const newKey = deliveryTypeKey === key ? null : key;
    setDeliveryTypeKey(newKey);
    onDeliveryTypeSelect?.(newKey);
    setWarehouseQuery(''); setWarehouseSuggestions([]); setSelectedWarehouse(null);
    setStreetQuery(''); setStreetSuggestions([]); setSelectedStreet(null);
    if (newKey === 'pickup') {
      setCityQuery('Київ');
      setSelectedNPCity(null);
      setSelectedHoroshopCity(null);
      setLoadingKyiv(true);
      try {
        const realOrderId = order.id + 16;
        const cities = await API.findHoroshopCities('Київ', realOrderId, order.userId);
        if (cities && cities.length > 0) setSelectedHoroshopCity(cities[0]);
      } catch {}
      setLoadingKyiv(false);
    }
  };

  const handleSave = async () => {
    setSaving(true);
    try {
      // 1. Тип доставки
      if (deliveryTypeKey) {
        const dt = DELIVERY_TYPES.find(d => d.key === deliveryTypeKey);
        if (dt) await API.setDeliveryType(order.id, dt.id, order.userId);
      }

      // 2. Атрибути
      const fields = {};

      if (selectedHoroshopCity) {
        fields['Recipient[delivery_city_id]']  = selectedHoroshopCity.id;
        fields['Recipient[delivery_city]']     = selectedHoroshopCity.label;
        fields['Recipient[np_city_name]']      = selectedHoroshopCity.NPCityDescription || selectedHoroshopCity.label;
      }

      if ((deliveryTypeKey === 'warehouse' || deliveryTypeKey === 'postomat') && selectedWarehouse) {
        fields['Delivery[delivery_method][@instance.parameters.destination.warehouse.id]']   = selectedWarehouse.Ref;
        fields['Delivery[delivery_method][@instance.parameters.destination.warehouse.name]'] = selectedWarehouse.Description;
      }

      if (deliveryTypeKey === 'courier' && selectedStreet) {
        fields['Delivery[delivery_method][@instance.parameters.destination.address.streetId]']           = selectedStreet.Ref;
        fields['Delivery[delivery_method][@instance.parameters.destination.address.streetName]']         = `${selectedStreet.StreetsType} ${selectedStreet.Description}`;
        fields['Delivery[delivery_method][@instance.parameters.destination.address.meta.streetUa]']      = selectedStreet.Description;
        fields['Delivery[delivery_method][@instance.parameters.destination.address.meta.streetType]']    = selectedStreet.StreetsType;
        if (building.trim()) fields['Delivery[delivery_method][@instance.parameters.destination.address.buildingNumber]'] = building.trim();
        if (flat.trim())     fields['Delivery[delivery_method][@instance.parameters.destination.address.flat]']           = flat.trim();
      }

      if (Object.keys(fields).length > 0) {
        await API.setAttributes(order.id, fields, order.userId);
      }

      // 3. Оновлюємо список
      const newDeliveryLabel = deliveryTypeKey ? (DELIVERY_TYPES.find(d => d.key === deliveryTypeKey)?.label || order.delivery) : order.delivery;
      let newAddressParts = [];
      if (selectedHoroshopCity) newAddressParts.push(selectedHoroshopCity.label);
      if ((deliveryTypeKey === 'warehouse' || deliveryTypeKey === 'postomat') && selectedWarehouse) newAddressParts.push(selectedWarehouse.Description);
      if (deliveryTypeKey === 'courier' && selectedStreet) {
        newAddressParts.push(`${selectedStreet.StreetsType} ${selectedStreet.Description}${building.trim() ? ', ' + building.trim() : ''}${flat.trim() ? '/' + flat.trim() : ''}`);
      }
      const newAddressText = newAddressParts.length > 0 ? newAddressParts.join(', ') : order.address;

      onFieldChange(order.id, { address: newAddressText, delivery: newDeliveryLabel });
      onClose();
    } catch (e) {
      alert('Помилка: ' + e.message);
    }
    setSaving(false);
  };

  const inputStyle = {
    width: '100%', boxSizing: 'border-box', height: 36, padding: '0 10px',
    background: 'var(--bg-raised)', color: 'var(--fg-primary)',
    border: '1px solid var(--border-default)', borderRadius: 8,
    fontSize: 13, fontFamily: 'inherit', outline: 'none',
  };
  const dropdownStyle = {
    position: 'absolute', top: 'calc(100% + 2px)', left: 0, right: 0,
    background: 'var(--bg-raised)', border: '1px solid var(--border-default)',
    borderRadius: 8, boxShadow: 'var(--shadow-1)', zIndex: 5,
    maxHeight: 200, overflowY: 'auto',
  };
  const dropItemStyle = {
    display: 'block', width: '100%', textAlign: 'left', padding: '8px 10px',
    border: 0, background: 'transparent', color: 'var(--fg-primary)',
    fontSize: 12, cursor: 'pointer', fontFamily: 'inherit',
  };

  const needsWarehouse = deliveryTypeKey === 'warehouse' || deliveryTypeKey === 'postomat';
  const needsStreet    = deliveryTypeKey === 'courier';
  const canSave = deliveryTypeKey || selectedHoroshopCity;

  return (
    <div style={{ marginTop: 10, padding: 14, background: 'var(--bg-raised)', border: '1px solid var(--border-default)', borderRadius: 10, display: 'flex', flexDirection: 'column', gap: 12 }}>

      {/* Тип доставки */}
      <div>
        <div style={{ fontSize: 11, fontWeight: 500, letterSpacing: '0.04em', textTransform: 'uppercase', color: 'var(--fg-muted)', marginBottom: 6 }}>Тип доставки</div>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
          {DELIVERY_TYPES.map(dt => (
            <button key={dt.key} onClick={() => handleDeliveryTypeClick(dt.key)} style={{
              height: 30, padding: '0 12px', borderRadius: 8, fontSize: 12, cursor: 'pointer', fontFamily: 'inherit',
              background: deliveryTypeKey === dt.key ? 'var(--accent-soft)' : 'transparent',
              color: deliveryTypeKey === dt.key ? 'var(--accent)' : 'var(--fg-secondary)',
              border: `1px solid ${deliveryTypeKey === dt.key ? 'var(--accent)' : 'var(--border-default)'}`,
              transition: 'all 120ms',
            }}>
              {dt.label}
            </button>
          ))}
        </div>
      </div>

      {/* Місто */}
      {deliveryTypeKey === 'pickup' ? (
        <div>
          <div style={{ fontSize: 11, fontWeight: 500, letterSpacing: '0.04em', textTransform: 'uppercase', color: 'var(--fg-muted)', marginBottom: 6 }}>Місто</div>
          <div style={{ padding: '8px 12px', background: 'var(--bg-raised)', border: '1px solid var(--accent)', borderRadius: 8, fontSize: 13, color: 'var(--fg-primary)', display: 'flex', alignItems: 'center', gap: 6 }}>
            {loadingKyiv ? <span style={{ color: 'var(--fg-muted)' }}>Завантаження…</span> : <>
              <span>Київ</span>
              {!selectedHoroshopCity && <span style={{ fontSize: 11, color: 'var(--warning)' }}>(не знайдено в Horoshop)</span>}
            </>}
          </div>
        </div>
      ) : (
        <div style={{ position: 'relative' }}>
          <div style={{ fontSize: 11, fontWeight: 500, letterSpacing: '0.04em', textTransform: 'uppercase', color: 'var(--fg-muted)', marginBottom: 6 }}>Місто</div>
          <input
            value={cityQuery}
            onChange={e => handleCityQueryChange(e.target.value)}
            placeholder="Введіть місто…"
            style={{ ...inputStyle, borderColor: selectedNPCity ? 'var(--accent)' : 'var(--border-default)' }}
          />
          {searchingCity && <div style={{ fontSize: 11, color: 'var(--fg-muted)', marginTop: 4 }}>Пошук…</div>}
          {citySuggestions.length > 0 && (
            <div style={dropdownStyle}>
              {citySuggestions.map((c, i) => (
                <button key={i} onMouseDown={() => handleSelectNPCity(c)} style={dropItemStyle}>
                  <span style={{ fontWeight: 500 }}>{c.MainDescription}</span>
                  {c.Area ? <span style={{ color: 'var(--fg-muted)', marginLeft: 6 }}>{c.Area}</span> : null}
                </button>
              ))}
            </div>
          )}
          {selectedNPCity && !selectedHoroshopCity && (
            <div style={{ fontSize: 11, color: 'var(--warning)', marginTop: 4 }}>Місто в Horoshop не знайдено</div>
          )}
        </div>
      )}

      {/* Відділення / Поштомат */}
      {needsWarehouse && selectedNPCity && (
        <div style={{ position: 'relative' }}>
          <div style={{ fontSize: 11, fontWeight: 500, letterSpacing: '0.04em', textTransform: 'uppercase', color: 'var(--fg-muted)', marginBottom: 6 }}>
            {deliveryTypeKey === 'postomat' ? 'Поштомат' : 'Відділення'}
          </div>
          <input
            value={warehouseQuery}
            onChange={e => handleWarehouseQueryChange(e.target.value)}
            placeholder="Номер або адреса…"
            style={{ ...inputStyle, borderColor: selectedWarehouse ? 'var(--accent)' : 'var(--border-default)' }}
          />
          {searchingWarehouse && <div style={{ fontSize: 11, color: 'var(--fg-muted)', marginTop: 4 }}>Пошук…</div>}
          {warehouseSuggestions.length > 0 && (
            <div style={dropdownStyle}>
              {warehouseSuggestions.map((w, i) => (
                <button key={i} onMouseDown={() => { setSelectedWarehouse(w); setWarehouseQuery(w.ShortAddress || w.Description); setWarehouseSuggestions([]); }} style={dropItemStyle}>
                  {w.Description}
                </button>
              ))}
            </div>
          )}
        </div>
      )}

      {/* Вулиця + будинок + квартира */}
      {needsStreet && selectedNPCity && (
        <>
          <div style={{ position: 'relative' }}>
            <div style={{ fontSize: 11, fontWeight: 500, letterSpacing: '0.04em', textTransform: 'uppercase', color: 'var(--fg-muted)', marginBottom: 6 }}>Вулиця</div>
            <input
              value={streetQuery}
              onChange={e => handleStreetQueryChange(e.target.value)}
              placeholder="Назва вулиці…"
              style={{ ...inputStyle, borderColor: selectedStreet ? 'var(--accent)' : 'var(--border-default)' }}
            />
            {searchingStreet && <div style={{ fontSize: 11, color: 'var(--fg-muted)', marginTop: 4 }}>Пошук…</div>}
            {streetSuggestions.length > 0 && (
              <div style={dropdownStyle}>
                {streetSuggestions.map((s, i) => (
                  <button key={i} onMouseDown={() => { setSelectedStreet(s); setStreetQuery(`${s.StreetsType} ${s.Description}`); setStreetSuggestions([]); }} style={dropItemStyle}>
                    {s.StreetsType} {s.Description}
                  </button>
                ))}
              </div>
            )}
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
            <div>
              <div style={{ fontSize: 11, color: 'var(--fg-muted)', marginBottom: 4 }}>Будинок</div>
              <input value={building} onChange={e => setBuilding(e.target.value)} placeholder="1А" style={inputStyle}/>
            </div>
            <div>
              <div style={{ fontSize: 11, color: 'var(--fg-muted)', marginBottom: 4 }}>Квартира</div>
              <input value={flat} onChange={e => setFlat(e.target.value)} placeholder="12" style={inputStyle}/>
            </div>
          </div>
        </>
      )}

      {/* Кнопки */}
      <div style={{ display: 'flex', gap: 8, paddingTop: 4 }}>
        <button onClick={handleSave} disabled={saving || !canSave} style={{
          flex: 1, height: 36, borderRadius: 8, border: 0, fontSize: 13, fontWeight: 500, cursor: (saving || !canSave) ? 'not-allowed' : 'pointer', fontFamily: 'inherit',
          background: canSave ? 'var(--accent)' : 'var(--bg-panel)', color: canSave ? '#fff' : 'var(--fg-muted)',
          opacity: saving ? 0.7 : 1, transition: 'all 120ms',
        }}>
          {saving ? 'Збереження…' : 'Зберегти доставку'}
        </button>
        <button onClick={onClose} style={{
          height: 36, padding: '0 14px', borderRadius: 8, border: '1px solid var(--border-default)',
          background: 'transparent', color: 'var(--fg-secondary)', fontSize: 13, cursor: 'pointer', fontFamily: 'inherit',
        }}>
          Скасувати
        </button>
      </div>
    </div>
  );
}

function normPhone(p) { return (p || '').replace(/\D/g, '').slice(-9); }

function OrderCallsSection({ phone }) {
  const [playingId, setPlayingId] = useState(null);
  const [progress, setProgress]   = useState(0);
  const audioRef = useRef(null);
  useEffect(() => () => { audioRef.current?.pause(); }, []);

  const op    = normPhone(phone);
  const calls = !op ? [] : (window._crmCalls?.data || [])
    .filter(c => normPhone(c.caller) === op || normPhone(c.dst) === op)
    .slice(0, 8);

  if (!calls.length) return null;

  const handleToggle = (call) => {
    if (!call.recording) return;
    if (playingId === call.uniqueid) {
      audioRef.current?.pause(); setPlayingId(null); setProgress(0); return;
    }
    if (audioRef.current) { audioRef.current.pause(); audioRef.current.ontimeupdate = null; audioRef.current.onended = null; }
    const audio = new Audio(call.recording);
    audio.ontimeupdate = () => { if (audio.duration) setProgress(Math.round((audio.currentTime / audio.duration) * 100)); };
    audio.onended = () => { setPlayingId(null); setProgress(0); };
    audioRef.current = audio;
    audio.play().catch(() => setPlayingId(null));
    setPlayingId(call.uniqueid); setProgress(0);
  };

  const dirIcon  = c => (c.call_type === 'in' || c.call_type === 'transitin') ? 'phone-incoming' : 'phone-outgoing';
  const dirColor = c => (c.call_type === 'in' || c.call_type === 'transitin') ? 'var(--credit)' : 'var(--fg-secondary)';

  return (
    <div>
      <div style={{ fontSize: 11, fontWeight: 500, letterSpacing: '0.04em', textTransform: 'uppercase', color: 'var(--fg-muted)', marginBottom: 10 }}>
        Дзвінки ({calls.length})
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
        {calls.map(c => {
          const isPlaying = playingId === c.uniqueid;
          return (
            <div key={c.uniqueid} style={{ background: 'var(--bg-raised)', border: '1px solid var(--border-subtle)', borderRadius: 8, padding: '10px 12px', display: 'flex', flexDirection: 'column', gap: 8 }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                <Icon name={dirIcon(c)} size={14} color={dirColor(c)}/>
                <span style={{ fontSize: 12, color: 'var(--fg-secondary)', flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{c.employee_fio || '—'}</span>
                <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: CALL_DISP_COLOR[c.disposition] || 'var(--fg-muted)' }}>{fmtDur(c.billsec)}</span>
                <span style={{ fontSize: 11, color: 'var(--fg-muted)', flexShrink: 0 }}>{fmtCallDate(c.calldate)}</span>
              </div>
              <CallPlayer recording={c.recording} playing={isPlaying} onToggle={() => handleToggle(c)} progress={isPlaying ? progress : 0}/>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function OrderDetail({ order, onClose, onStatusChange, onPaymentChange, onPhoneChange, onFieldChange, supplierMap = {} }) {
  const [dropStatus, setDropStatus]     = useState(false);
  const [dropPayment, setDropPayment]   = useState(false);
  const [localStatus, setLocalStatus]   = useState(order?.status);
  const [localPayment, setLocalPayment] = useState(order?.payment);
  const [pendingStatus, setPendingStatus]   = useState(null);
  const [pendingPayment, setPendingPayment] = useState(null);
  const [saving, setSaving]             = useState(false);
  const [editPhone, setEditPhone]           = useState(false);
  const [phoneVal, setPhoneVal]             = useState(order?.phone || "");
  const [editName, setEditName]             = useState(false);
  const [nameVal, setNameVal]               = useState(order?.client || "");
  const [commentVal, setCommentVal]         = useState(order?.managerComment || "");
  const [savingField, setSavingField]       = useState(null);
  const [editDelivery, setEditDelivery]     = useState(false);
  const [localDeliveryKey, setLocalDeliveryKey] = useState(() => deriveDeliveryKey(order?.delivery));

  useEffect(() => {
    setLocalStatus(order?.status); setLocalPayment(order?.payment);
    setPendingStatus(null); setPendingPayment(null);
    setDropStatus(false); setDropPayment(false);
    setEditPhone(false); setPhoneVal(order?.phone || "");
    setEditName(false); setNameVal(order?.client || "");
    setCommentVal(order?.managerComment || "");
    setEditDelivery(false);
    setLocalDeliveryKey(deriveDeliveryKey(order?.delivery));
  }, [order?.id]);

  useEffect(() => {
    setLocalDeliveryKey(deriveDeliveryKey(order?.delivery));
  }, [order?.delivery]);

  const blockedPaymentIds =
    localDeliveryKey === 'postomat' ? new Set([15]) :
    localDeliveryKey === 'pickup'   ? new Set([29, 32]) : new Set();

  useEffect(() => {
    if (pendingPayment && blockedPaymentIds.has(pendingPayment.id)) setPendingPayment(null);
  }, [localDeliveryKey]);

  if (!order) return null;

  const locked = !!order.ttn?.number;
  const hasPending = pendingStatus || pendingPayment;

  const handleDone = async () => {
    setSaving(true);
    try {
      if (pendingStatus) {
        const newId = STATUSES[pendingStatus]?.horoshopId;
        await API.setOrderStatus(order.id, newId);
        setLocalStatus(pendingStatus);
        onStatusChange(order.id, pendingStatus);
        setPendingStatus(null);
      }
      if (pendingPayment) {
        await API.setPaymentType(order.id, pendingPayment.id, order.userId);
        const fresh = await API.getOrder(order.id).catch(() => null);
        const mapped = fresh ? mapOrder(fresh.response.order) : null;
        const newPayment = mapped?.payment || pendingPayment.label;
        const newPaymentPrice = mapped?.paymentPrice ?? order.paymentPrice;
        setLocalPayment(newPayment);
        onPaymentChange(order.id, newPayment, newPaymentPrice);
        setPendingPayment(null);
      }
    } catch (e) {
      alert("Помилка: " + e.message);
      setSaving(false);
      return;
    }
    setSaving(false);
    onClose();
  };

  const saveAttr = async (fields, onSuccess) => {
    try {
      await API.setAttributes(order.id, fields, order.userId);
      onSuccess();
    } catch (e) {
      alert("Помилка: " + e.message);
      throw e;
    }
  };

  const handleSavePhone = async () => {
    if (!phoneVal.trim() || phoneVal.trim() === order.phone) { setEditPhone(false); return; }
    setSavingField('phone');
    try {
      await saveAttr({ 'Recipient[delivery_phone]': phoneVal.trim() }, () => {
        onFieldChange(order.id, { phone: phoneVal.trim() });
        setEditPhone(false);
      });
    } finally { setSavingField(null); }
  };

  const handleSaveName = async () => {
    if (!nameVal.trim() || nameVal.trim() === order.client) { setEditName(false); return; }
    setSavingField('name');
    try {
      await saveAttr({ 'Recipient[delivery_name]': nameVal.trim() }, () => {
        onFieldChange(order.id, { client: nameVal.trim() });
        setEditName(false);
      });
    } finally { setSavingField(null); }
  };

  const handleSaveComment = async () => {
    if (commentVal === (order.managerComment || "")) return;
    setSavingField('comment');
    try {
      await saveAttr({ 'Recipient[admin_comment]': commentVal }, () => {
        onFieldChange(order.id, { managerComment: commentVal });
      });
    } finally { setSavingField(null); }
  };

  const Field = ({ label, value, mono }) => (
    <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
      <span style={{ fontSize: 11, fontWeight: 500, letterSpacing: "0.04em", textTransform: "uppercase", color: "var(--fg-muted)" }}>{label}</span>
      <span style={{ fontSize: 13, color: "var(--fg-primary)", fontFamily: mono ? "var(--font-mono)" : "inherit" }}>{value || "—"}</span>
    </div>
  );

  const dropBtn = (label, onClick, pending) => ({
    display: "flex", alignItems: "center", justifyContent: "space-between", width: "100%",
    height: 40, padding: "0 14px", fontFamily: "inherit", fontSize: 13, cursor: "pointer",
    background: pending ? "var(--accent-soft)" : "var(--bg-raised)",
    color: pending ? "var(--accent)" : "var(--fg-primary)",
    border: `1px solid ${pending ? "var(--accent)" : "var(--border-default)"}`,
    borderRadius: 8,
  });

  return (
    <div style={{
      position: "fixed", top: 0, right: 0, width: 480, height: "100dvh",
      background: "var(--bg-panel)", borderLeft: "1px solid var(--border-subtle)",
      boxShadow: "var(--shadow-2)", display: "flex", flexDirection: "column", zIndex: 20,
      animation: "slideIn 200ms cubic-bezier(.2,0,0,1)",
    }}>
      {/* Header */}
      <div style={{ display: "flex", alignItems: "center", padding: "16px 24px", borderBottom: "1px solid var(--border-subtle)", flexShrink: 0, gap: 10 }}>
        <div style={{ flex: 1, display: "flex", flexDirection: "column", gap: 6 }}>
          <h2 style={{ fontSize: 20, fontWeight: 600, margin: 0, color: "var(--fg-primary)" }}>Замовлення №{order.id}</h2>
          {(() => { const s = supplierMap[String(order.id)]; return s ? <div style={{ display: "flex", alignItems: "center", gap: 6 }}><span style={{ fontSize: 11, color: "var(--fg-muted)" }}>Відповідь постачальника:</span><SupplierBadge status={s.status} supplierResponse={s.supplierResponse}/></div> : null; })()}
        </div>
        <button onClick={onClose} style={{ width: 32, height: 32, border: 0, background: "transparent", color: "var(--fg-secondary)", borderRadius: 6, cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center" }}>
          <Icon name="x" size={18}/>
        </button>
      </div>

      {/* Scrollable body */}
      <div style={{ flex: 1, overflow: "auto", padding: "20px 24px", display: "flex", flexDirection: "column", gap: 20 }}>

        {/* Status */}
        <div>
          <div style={{ fontSize: 11, fontWeight: 500, letterSpacing: "0.04em", textTransform: "uppercase", color: "var(--fg-muted)", marginBottom: 8 }}>Статус</div>
          <div style={{ position: "relative" }}>
            <button onClick={() => { setDropStatus(d => !d); setDropPayment(false); }} style={dropBtn(null, null, !!pendingStatus)}>
              <StatusChip status={pendingStatus || localStatus}/>
              <Icon name="chevron-down" size={16} style={{ color: "var(--fg-muted)" }}/>
            </button>
            {dropStatus && (
              <>
                <div onClick={() => setDropStatus(false)} style={{ position: "fixed", inset: 0, zIndex: 4 }}/>
                <div style={{ position: "absolute", top: "calc(100% + 4px)", left: 0, right: 0, background: "var(--bg-raised)", border: "1px solid var(--border-default)", borderRadius: 8, padding: 4, boxShadow: "var(--shadow-1)", zIndex: 5 }}>
                  {Object.keys(STATUSES).map(s => {
                    const active = (pendingStatus || localStatus) === s;
                    return (
                      <button key={s} onClick={() => { setPendingStatus(s === localStatus ? null : s); setDropStatus(false); }} style={{
                        display: "flex", alignItems: "center", justifyContent: "space-between", width: "100%", padding: "8px 10px",
                        border: 0, borderRadius: 6, background: active ? "var(--bg-active)" : "transparent",
                        cursor: "pointer", textAlign: "left", fontFamily: "inherit",
                      }}>
                        <StatusChip status={s}/>
                        {active && <Icon name="check" size={14} color="var(--accent)"/>}
                      </button>
                    );
                  })}
                </div>
              </>
            )}
          </div>
        </div>

        {/* Client */}
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
          <div>
            <div style={{ fontSize: 11, fontWeight: 500, letterSpacing: "0.04em", textTransform: "uppercase", color: "var(--fg-muted)", marginBottom: 6 }}>Клієнт</div>
            {editName ? (
              <div style={{ display: "flex", gap: 6 }}>
                <input value={nameVal} onChange={e => setNameVal(e.target.value)} autoFocus
                  onKeyDown={e => { if (e.key === "Enter") handleSaveName(); if (e.key === "Escape") setEditName(false); }}
                  style={{ flex: 1, height: 32, padding: "0 10px", background: "var(--bg-raised)", color: "var(--fg-primary)", border: "1px solid var(--accent)", borderRadius: 6, fontSize: 13, fontFamily: "inherit", outline: "none" }}/>
                <button onClick={handleSaveName} disabled={savingField === 'name'} style={{ height: 32, padding: "0 10px", background: "var(--accent)", color: "#fff", border: 0, borderRadius: 6, fontSize: 12, cursor: "pointer", fontFamily: "inherit" }}>
                  {savingField === 'name' ? "…" : "OK"}
                </button>
                <button onClick={() => setEditName(false)} style={{ height: 32, width: 32, background: "var(--bg-raised)", border: "1px solid var(--border-default)", borderRadius: 6, cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", color: "var(--fg-muted)" }}>
                  <Icon name="x" size={13}/>
                </button>
              </div>
            ) : (
              <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                <span style={{ fontSize: 13, color: "var(--fg-primary)" }}>{order.client || "—"}</span>
                {!locked && <button onClick={() => { setNameVal(order.client); setEditName(true); }} style={{ height: 22, padding: "0 8px", background: "transparent", border: "1px solid var(--border-default)", borderRadius: 4, color: "var(--fg-muted)", fontSize: 11, cursor: "pointer", fontFamily: "inherit" }}>Змінити</button>}
              </div>
            )}
          </div>
          <Field label="Email" value={order.email}/>
        </div>

        {/* Phone */}
        <div>
          <div style={{ fontSize: 11, fontWeight: 500, letterSpacing: "0.04em", textTransform: "uppercase", color: "var(--fg-muted)", marginBottom: 6 }}>Телефон</div>
          {editPhone ? (
            <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
              <input value={phoneVal} onChange={e => setPhoneVal(e.target.value)} autoFocus
                onKeyDown={e => { if (e.key === "Enter") handleSavePhone(); if (e.key === "Escape") setEditPhone(false); }}
                style={{ flex: 1, height: 36, padding: "0 12px", background: "var(--bg-raised)", color: "var(--fg-primary)", border: "1px solid var(--accent)", borderRadius: 8, fontSize: 14, fontFamily: "var(--font-mono)", outline: "none" }}/>
              <button onClick={handleSavePhone} disabled={savingField === 'phone'} style={{ height: 36, padding: "0 14px", background: "var(--accent)", color: "#fff", border: 0, borderRadius: 8, fontSize: 13, cursor: "pointer", fontFamily: "inherit" }}>
                {savingField === 'phone' ? "…" : "Зберегти"}
              </button>
              <button onClick={() => setEditPhone(false)} style={{ height: 36, width: 36, background: "var(--bg-raised)", border: "1px solid var(--border-default)", borderRadius: 8, cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", color: "var(--fg-muted)" }}>
                <Icon name="x" size={14}/>
              </button>
            </div>
          ) : (
            <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
              <a href={`tel:${order.phone}`} style={{ fontFamily: "var(--font-mono)", fontSize: 14, color: "var(--fg-primary)", textDecoration: "none" }}>{fmtPhone(order.phone)}</a>
              <div style={{ display: "flex", gap: 6 }}>
                <MessengerBtn kind="viber"    phone={order.phone}/>
                <MessengerBtn kind="whatsapp" phone={order.phone}/>
                <MessengerBtn kind="telegram" phone={order.phone}/>
              </div>
              {!locked && (
                <button onClick={() => { setPhoneVal(order.phone); setEditPhone(true); }} style={{ height: 26, padding: "0 10px", background: "transparent", border: "1px solid var(--border-default)", borderRadius: 6, color: "var(--fg-secondary)", fontSize: 12, cursor: "pointer", fontFamily: "inherit" }}>
                  Змінити
                </button>
              )}
            </div>
          )}
        </div>

        {/* Address */}
        <div>
          <div style={{ fontSize: 11, fontWeight: 500, letterSpacing: "0.04em", textTransform: "uppercase", color: "var(--fg-muted)", marginBottom: 6 }}>Адреса доставки</div>
          <div style={{ display: "flex", flexDirection: "column", gap: 6, alignItems: "flex-start" }}>
            <div style={{ width: "100%", display: "flex", gap: 8, padding: "10px 12px", background: "var(--bg-raised)", border: "1px solid var(--border-default)", borderRadius: 8 }}>
              <Icon name="map-pin" size={16} style={{ marginTop: 2, color: "var(--fg-muted)", flexShrink: 0 }}/>
              <div style={{ fontSize: 13, color: "var(--fg-primary)", lineHeight: 1.45 }}>
                <div>{order.address || "—"}</div>
                <div style={{ fontSize: 12, color: "var(--fg-muted)", marginTop: 3 }}>{order.delivery}</div>
              </div>
            </div>
            {!locked && !editDelivery && (
              <button onClick={() => setEditDelivery(true)} style={{ width: "100%", height: 26, padding: "0 10px", background: "transparent", border: "1px solid var(--border-default)", borderRadius: 6, color: "var(--fg-secondary)", fontSize: 12, cursor: "pointer", fontFamily: "inherit" }}>Змінити</button>
            )}
          </div>
          {!locked && editDelivery && (
            <DeliveryEditor
              order={order}
              onFieldChange={onFieldChange}
              onDeliveryTypeSelect={setLocalDeliveryKey}
              onClose={() => setEditDelivery(false)}
            />
          )}
        </div>

        {/* TTN */}
        {order.ttn?.number && (
          <div>
            <div style={{ fontSize: 11, fontWeight: 500, letterSpacing: "0.04em", textTransform: "uppercase", color: "var(--fg-muted)", marginBottom: 6 }}>ТТН</div>
            <div style={{ padding: "10px 14px", background: "var(--bg-raised)", border: "1px solid var(--border-default)", borderRadius: 8, display: "flex", flexDirection: "column", gap: 4 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                <Icon name="package" size={14} style={{ color: "var(--fg-muted)", flexShrink: 0 }}/>
                <span style={{ fontFamily: "var(--font-mono)", fontSize: 13, fontWeight: 600, color: "var(--fg-primary)" }}>{order.ttn.number}</span>
                <button onClick={() => copyText(order.ttn.number)} title="Скопіювати ТТН" style={{ height: 22, width: 22, display: "flex", alignItems: "center", justifyContent: "center", background: "transparent", border: "1px solid var(--border-default)", borderRadius: 4, cursor: "pointer", color: "var(--fg-muted)", flexShrink: 0 }}>
                  <Icon name="copy" size={11}/>
                </button>
              </div>
              {order.ttn.status && <div style={{ fontSize: 12, color: "var(--accent)", paddingLeft: 22 }}>{order.ttn.status}</div>}
              {order.ttn.deliveryDate && <div style={{ fontSize: 12, color: "var(--fg-muted)", paddingLeft: 22 }}>Очікувана доставка: {order.ttn.deliveryDate}</div>}
              {order.ttn.updatedAt && <div style={{ fontSize: 11, color: "var(--fg-muted)", paddingLeft: 22 }}>Оновлено: {order.ttn.updatedAt}</div>}
            </div>
          </div>
        )}

        {/* Payment */}
        <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16, alignItems: "end" }}>
            <div style={{ minWidth: 0 }}>
              <div style={{ fontSize: 11, fontWeight: 500, letterSpacing: "0.04em", textTransform: "uppercase", color: "var(--fg-muted)", marginBottom: 8 }}>Спосіб оплати</div>
              <div style={{ position: "relative" }}>
                {locked ? (
                  <div style={{ height: 36, padding: "0 12px", display: "flex", alignItems: "center", background: "var(--bg-raised)", border: "1px solid var(--border-default)", borderRadius: 8, fontSize: 13, color: "var(--fg-primary)" }}>
                    {localPayment || "—"}
                  </div>
                ) : (
                  <>
                    <button onClick={() => { setDropPayment(d => !d); setDropStatus(false); }} style={dropBtn(null, null, !!pendingPayment)}>
                      <span style={{ fontSize: 13, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
                        {pendingPayment?.label || localPayment || "—"}
                      </span>
                      <Icon name="chevron-down" size={16} style={{ color: "var(--fg-muted)", flexShrink: 0 }}/>
                    </button>
                    {dropPayment && (
                      <>
                        <div onClick={() => setDropPayment(false)} style={{ position: "fixed", inset: 0, zIndex: 4 }}/>
                        <div style={{ position: "absolute", top: "calc(100% + 4px)", left: 0, right: 0, background: "var(--bg-raised)", border: "1px solid var(--border-default)", borderRadius: 8, padding: 4, boxShadow: "var(--shadow-1)", zIndex: 5 }}>
                          {PAYMENT_TYPES.filter(pt => !blockedPaymentIds.has(pt.id)).map(pt => {
                            const active = (pendingPayment?.id === pt.id);
                            return (
                              <button key={pt.id} onClick={() => { setPendingPayment(active ? null : pt); setDropPayment(false); }} style={{
                                display: "flex", alignItems: "center", justifyContent: "space-between", width: "100%", padding: "8px 10px",
                                border: 0, borderRadius: 6, background: active ? "var(--bg-active)" : "transparent",
                                cursor: "pointer", textAlign: "left", fontFamily: "inherit", fontSize: 13, color: "var(--fg-primary)",
                              }}>
                                {pt.label}
                                {active && <Icon name="check" size={14} color="var(--accent)"/>}
                              </button>
                            );
                          })}
                        </div>
                      </>
                    )}
                  </>
                )}
              </div>
            </div>
            <div>
              <div style={{ fontSize: 11, fontWeight: 500, letterSpacing: "0.04em", textTransform: "uppercase", color: "var(--fg-muted)", marginBottom: 6 }}>Статус оплати</div>
              <PaidBadge payed={order.payed}/>
            </div>
          </div>
          {order.paymentPrice > 0 && (
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "8px 12px", background: "var(--bg-raised)", border: "1px solid var(--border-subtle)", borderRadius: 8 }}>
              <span style={{ fontSize: 13, color: "var(--fg-secondary)" }}>Комісія за оплату</span>
              <span style={{ fontFamily: "var(--font-mono)", fontSize: 13, fontWeight: 500, color: "var(--debit)" }}>{fmtMoney(order.paymentPrice)}</span>
            </div>
          )}
        </div>

        {/* Products */}
        <div>
          <div style={{ fontSize: 11, fontWeight: 500, letterSpacing: "0.04em", textTransform: "uppercase", color: "var(--fg-muted)", marginBottom: 8 }}>Товари</div>
          <div style={{ background: "var(--bg-raised)", border: "1px solid var(--border-subtle)", borderRadius: 8, overflow: "hidden" }}>
            {order.productsRaw.length ? order.productsRaw.map((p, i) => (
              <div key={i} style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", padding: "10px 14px", borderBottom: i < order.productsRaw.length - 1 ? "1px solid var(--border-subtle)" : "none", gap: 12 }}>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 13, color: "var(--fg-primary)" }}>{p.title}</div>
                  {p.article && <div style={{ fontSize: 11, color: "var(--fg-muted)", marginTop: 2 }}>Арт: {p.article}</div>}
                </div>
                <div style={{ textAlign: "right", flexShrink: 0 }}>
                  <div style={{ fontFamily: "var(--font-mono)", fontSize: 13, fontWeight: 500, color: "var(--fg-primary)" }}>{fmtMoney(p.total_price ?? p.price)}</div>
                  <div style={{ fontSize: 11, color: "var(--fg-muted)", marginTop: 2 }}>{p.quantity} шт × {fmtMoney(p.price)}</div>
                </div>
              </div>
            )) : (
              <div style={{ padding: "12px 14px", fontSize: 13, color: "var(--fg-muted)" }}>Товари не вказані</div>
            )}
          </div>
        </div>

        {/* Total */}
        <div style={{ borderTop: "1px solid var(--border-subtle)", borderBottom: "1px solid var(--border-subtle)", padding: "12px 0", display: "flex", flexDirection: "column", gap: 8 }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
            <span style={{ fontSize: 13, color: "var(--fg-secondary)" }}>Сума товарів</span>
            <span style={{ fontFamily: "var(--font-mono)", fontVariantNumeric: "tabular-nums", fontSize: 14, fontWeight: 500, color: "var(--fg-primary)" }}>{fmtMoney(order.totalDefault)}</span>
          </div>
          {order.paymentPrice > 0 && (
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
              <span style={{ fontSize: 13, color: "var(--fg-secondary)" }}>Комісія за оплату</span>
              <span style={{ fontFamily: "var(--font-mono)", fontSize: 13, color: "var(--debit)" }}>+ {fmtMoney(order.paymentPrice)}</span>
            </div>
          )}
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", paddingTop: 8, borderTop: "1px solid var(--border-subtle)" }}>
            <span style={{ fontSize: 14, fontWeight: 600, color: "var(--fg-primary)" }}>До сплати</span>
            <span style={{ fontFamily: "var(--font-mono)", fontVariantNumeric: "tabular-nums", fontSize: 20, fontWeight: 700, color: "var(--fg-primary)" }}>{fmtMoney(order.totalDefault + order.paymentPrice)}</span>
          </div>
        </div>

        {/* Comments */}
        <div>
          <div style={{ fontSize: 11, fontWeight: 500, letterSpacing: "0.04em", textTransform: "uppercase", color: "var(--fg-muted)", marginBottom: 10 }}>Коментарі</div>
          {order.comment && (
            <div style={{ background: "var(--bg-raised)", border: "1px solid var(--border-subtle)", borderRadius: 10, padding: 12, marginBottom: 8 }}>
              <div style={{ fontSize: 11, color: "var(--fg-muted)", marginBottom: 4 }}>Покупець</div>
              <p style={{ margin: 0, fontSize: 13, color: "var(--fg-secondary)", lineHeight: 1.5 }}>{order.comment}</p>
            </div>
          )}
          <div>
            <div style={{ fontSize: 11, color: "var(--fg-muted)", marginBottom: 6 }}>Коментар менеджера</div>
            <textarea value={commentVal} onChange={e => setCommentVal(e.target.value)}
              placeholder="Додати коментар…" rows={3}
              style={{ width: "100%", boxSizing: "border-box", padding: "10px 12px", background: "var(--bg-raised)", color: "var(--fg-primary)", border: "1px solid var(--border-default)", borderRadius: 10, fontSize: 13, fontFamily: "inherit", resize: "vertical", outline: "none", lineHeight: 1.5 }}/>
            {commentVal !== (order.managerComment || "") && (
              <div style={{ display: "flex", justifyContent: "flex-end", gap: 6, marginTop: 6 }}>
                <button onClick={() => setCommentVal(order.managerComment || "")} style={{ height: 30, padding: "0 12px", background: "transparent", border: "1px solid var(--border-default)", borderRadius: 6, color: "var(--fg-secondary)", fontSize: 12, cursor: "pointer", fontFamily: "inherit" }}>Скасувати</button>
                <button onClick={handleSaveComment} disabled={savingField === 'comment'} style={{ height: 30, padding: "0 12px", background: "var(--accent)", color: "#fff", border: 0, borderRadius: 6, fontSize: 12, cursor: "pointer", fontFamily: "inherit" }}>
                  {savingField === 'comment' ? "Збереження…" : "Зберегти"}
                </button>
              </div>
            )}
          </div>
        </div>

        <OrderCallsSection phone={order.phone}/>

        <div style={{ fontSize: 12, color: "var(--fg-muted)" }}>Створено: {order.created}</div>
      </div>

      {/* Footer */}
      <div style={{ padding: "12px 24px", borderTop: "1px solid var(--border-subtle)", flexShrink: 0 }}>
        <button onClick={handleDone} disabled={saving} style={{
          width: "100%", height: 40, borderRadius: 8,
          background: hasPending ? "var(--accent)" : "var(--bg-raised)",
          color: hasPending ? "#fff" : "var(--fg-secondary)",
          border: `1px solid ${hasPending ? "transparent" : "var(--border-default)"}`,
          fontSize: 14, fontWeight: 500, cursor: saving ? "wait" : "pointer", fontFamily: "inherit",
          transition: "all 120ms",
        }}>
          {saving ? "Збереження…" : "Готово"}
        </button>
      </div>
    </div>
  );
}

// ── Mobile orders ─────────────────────────────────────────────────
function MobileStatusFilters({ active, onChange, orders }) {
  const items = [["all","Усі",orders.length], ...Object.keys(STATUSES).map(k => [k, STATUSES[k].label, orders.filter(o => o.status === k).length])];
  return (
    <div style={{ display: "flex", gap: 6, padding: "8px 16px 12px", overflowX: "auto", borderBottom: "1px solid var(--border-subtle)", flexShrink: 0, scrollbarWidth: "none" }}>
      {items.map(([k, label, count]) => {
        const isActive = active === k;
        return (
          <button key={k} onClick={() => onChange(k)} style={{
            display: "inline-flex", alignItems: "center", gap: 6, height: 28, padding: "0 12px",
            background: isActive ? "var(--accent-soft)" : "var(--bg-panel)",
            color: isActive ? "var(--accent)" : "var(--fg-secondary)",
            border: `1px solid ${isActive ? "transparent" : "var(--border-default)"}`,
            borderRadius: 999, fontSize: 12, fontWeight: 500, cursor: "pointer",
            whiteSpace: "nowrap", flexShrink: 0, fontFamily: "inherit",
          }}>
            {label}
            <span style={{ fontSize: 10, color: isActive ? "var(--accent)" : "var(--fg-muted)", fontFamily: "var(--font-mono)" }}>{count}</span>
          </button>
        );
      })}
    </div>
  );
}

function OrderCardMobile({ o, onOpen, supplierInfo }) {
  return (
    <div onClick={() => onOpen(o)} style={{
      background: "var(--bg-panel)", border: "1px solid var(--border-subtle)", borderRadius: 12,
      padding: 14, display: "flex", flexDirection: "column", gap: 8, cursor: "pointer",
    }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 6 }}>
        <div style={{ display: "flex", gap: 6, alignItems: "center", flexWrap: "wrap", flex: 1, minWidth: 0 }}>
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--fg-muted)" }}>#{o.id}</span>
          {supplierInfo && <SupplierBadge status={supplierInfo.status} supplierResponse={supplierInfo.supplierResponse}/>}
        </div>
        <div style={{ display: "flex", flexDirection: "column", alignItems: "flex-end", gap: 4, flexShrink: 0 }}>
          <StatusChip status={o.status}/>
          <PaidBadge payed={o.payed}/>
        </div>
      </div>
      <span style={{ fontSize: 14, fontWeight: 500, color: "var(--fg-primary)" }}>{o.client}</span>
      <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--fg-secondary)" }}>{fmtPhone(o.phone)}</span>
      <span style={{ fontSize: 12, color: "var(--fg-secondary)", lineHeight: 1.4 }}>{o.products.slice(0,2).join(" · ")}{o.products.length > 2 ? ` +${o.products.length - 2}` : ""}</span>
      {o.address && (
        <div style={{ display: "flex", gap: 6, alignItems: "flex-start", fontSize: 11, color: "var(--fg-muted)" }}>
          <Icon name="map-pin" size={12} style={{ marginTop: 2, flexShrink: 0 }}/>
          <span style={{ lineHeight: 1.35 }}>{o.address}</span>
        </div>
      )}
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", paddingTop: 8, borderTop: "1px solid var(--border-subtle)" }}>
        <span style={{ fontSize: 11, color: "var(--fg-muted)" }}>{o.created}</span>
        <span style={{ fontFamily: "var(--font-mono)", fontVariantNumeric: "tabular-nums", fontSize: 14, fontWeight: 600, color: "var(--fg-primary)" }}>{fmtMoney(o.total)}</span>
      </div>
    </div>
  );
}

function OrderDetailSheetMobile({ order, onClose, onStatusChange, onPaymentChange, onPhoneChange, onFieldChange, supplierMap = {} }) {
  const [dropStatus, setDropStatus]     = useState(false);
  const [dropPayment, setDropPayment]   = useState(false);
  const [localPayment, setLocalPayment] = useState(order?.payment);
  const [pendingStatus, setPendingStatus]   = useState(null);
  const [pendingPayment, setPendingPayment] = useState(null);
  const [saving, setSaving]             = useState(false);
  const [editPhone, setEditPhone]       = useState(false);
  const [phoneVal, setPhoneVal]         = useState(order?.phone || "");
  const [editName, setEditName]         = useState(false);
  const [nameVal, setNameVal]           = useState(order?.client || "");
  const [commentVal, setCommentVal]     = useState(order?.managerComment || "");
  const [savingField, setSavingField]   = useState(null);
  const [editDelivery, setEditDelivery] = useState(false);
  const [localDeliveryKey, setLocalDeliveryKey] = useState(() => deriveDeliveryKey(order?.delivery));

  useEffect(() => {
    setPendingStatus(null); setPendingPayment(null);
    setLocalPayment(order?.payment);
    setDropStatus(false); setDropPayment(false);
    setEditPhone(false); setPhoneVal(order?.phone || "");
    setEditName(false); setNameVal(order?.client || "");
    setCommentVal(order?.managerComment || "");
    setEditDelivery(false);
    setLocalDeliveryKey(deriveDeliveryKey(order?.delivery));
  }, [order?.id]);

  useEffect(() => {
    setLocalDeliveryKey(deriveDeliveryKey(order?.delivery));
  }, [order?.delivery]);

  const blockedPaymentIds =
    localDeliveryKey === 'postomat' ? new Set([15]) :
    localDeliveryKey === 'pickup'   ? new Set([29, 32]) : new Set();

  useEffect(() => {
    if (pendingPayment && blockedPaymentIds.has(pendingPayment.id)) setPendingPayment(null);
  }, [localDeliveryKey]);

  const saveAttr = async (fields, onSuccess) => {
    try {
      await API.setAttributes(order.id, fields, order.userId);
      onSuccess();
    } catch (e) { alert("Помилка: " + e.message); throw e; }
  };

  const handleSavePhone = async () => {
    if (!phoneVal.trim() || phoneVal.trim() === order.phone) { setEditPhone(false); return; }
    setSavingField('phone');
    try {
      await saveAttr({ 'Recipient[delivery_phone]': phoneVal.trim() }, () => {
        onFieldChange(order.id, { phone: phoneVal.trim() });
        setEditPhone(false);
      });
    } finally { setSavingField(null); }
  };

  const handleSaveName = async () => {
    if (!nameVal.trim() || nameVal.trim() === order.client) { setEditName(false); return; }
    setSavingField('name');
    try {
      await saveAttr({ 'Recipient[delivery_name]': nameVal.trim() }, () => {
        onFieldChange(order.id, { client: nameVal.trim() });
        setEditName(false);
      });
    } finally { setSavingField(null); }
  };

  const handleSaveComment = async () => {
    if (commentVal === (order.managerComment || "")) return;
    setSavingField('comment');
    try {
      await saveAttr({ 'Recipient[admin_comment]': commentVal }, () => {
        onFieldChange(order.id, { managerComment: commentVal });
      });
    } finally { setSavingField(null); }
  };

  if (!order) return null;

  const locked = !!order.ttn?.number;
  const hasPending = pendingStatus || pendingPayment;

  const handleDone = async () => {
    setSaving(true);
    try {
      if (pendingStatus) {
        const newId = STATUSES[pendingStatus]?.horoshopId;
        await API.setOrderStatus(order.id, newId);
        onStatusChange(order.id, pendingStatus);
        setPendingStatus(null);
      }
      if (pendingPayment) {
        await API.setPaymentType(order.id, pendingPayment.id, order.userId);
        const fresh = await API.getOrder(order.id).catch(() => null);
        const mapped = fresh ? mapOrder(fresh.response.order) : null;
        const newPayment = mapped?.payment || pendingPayment.label;
        const newPaymentPrice = mapped?.paymentPrice ?? order.paymentPrice;
        setLocalPayment(newPayment);
        onPaymentChange(order.id, newPayment, newPaymentPrice);
        setPendingPayment(null);
      }
    } catch (e) {
      alert("Помилка: " + e.message);
      setSaving(false);
      return;
    }
    setSaving(false);
    onClose();
  };

  const Label = ({ text }) => (
    <div style={{ fontSize: 11, fontWeight: 500, letterSpacing: "0.04em", textTransform: "uppercase", color: "var(--fg-muted)", marginBottom: 6 }}>{text}</div>
  );

  const MobileDrop = ({ open, onToggle, display, children }) => (
    <div style={{ position: "relative" }}>
      <button onClick={onToggle} style={{
        display: "flex", alignItems: "center", justifyContent: "space-between", width: "100%",
        height: 42, padding: "0 14px", borderRadius: 10, fontFamily: "inherit", fontSize: 14,
        background: open ? "var(--bg-active)" : "var(--bg-raised)",
        border: "1px solid var(--border-default)", color: "var(--fg-primary)", cursor: "pointer",
      }}>
        {display}
        <Icon name="chevron-down" size={16} style={{ color: "var(--fg-muted)", flexShrink: 0, transform: open ? "rotate(180deg)" : "none", transition: "transform 150ms" }}/>
      </button>
      {open && (
        <>
          <div onClick={() => { setDropStatus(false); setDropPayment(false); }} style={{ position: "fixed", inset: 0, zIndex: 4 }}/>
          <div style={{ position: "absolute", top: "calc(100% + 4px)", left: 0, right: 0, background: "var(--bg-raised)", border: "1px solid var(--border-default)", borderRadius: 10, padding: 4, boxShadow: "var(--shadow-1)", zIndex: 5 }}>
            {children}
          </div>
        </>
      )}
    </div>
  );

  return (
    // position:fixed покриває весь viewport включно з BottomTabs
    <div style={{ position: "fixed", inset: 0, background: "rgba(0,0,0,.6)", zIndex: 100, display: "flex", flexDirection: "column", justifyContent: "flex-end" }} onClick={onClose}>
      <div onClick={e => e.stopPropagation()} style={{ background: "var(--bg-panel)", borderRadius: "16px 16px 0 0", maxHeight: "92dvh", display: "flex", flexDirection: "column", animation: "slideUp 200ms cubic-bezier(.2,0,0,1)" }}>
        {/* Drag handle */}
        <div style={{ display: "flex", justifyContent: "center", padding: "8px 0", flexShrink: 0 }}>
          <div style={{ width: 36, height: 4, borderRadius: 2, background: "rgba(255,255,255,.2)" }}/>
        </div>
        {/* Header */}
        <div style={{ display: "flex", alignItems: "center", padding: "0 16px 12px", borderBottom: "1px solid var(--border-subtle)", flexShrink: 0 }}>
          <div style={{ flex: 1 }}>
            <h2 style={{ fontSize: 18, fontWeight: 600, margin: 0, color: "var(--fg-primary)", marginBottom: 4 }}>Замовлення №{order.id}</h2>
            {(() => { const s = supplierMap[String(order.id)]; return s ? <div style={{ display: "flex", alignItems: "center", gap: 5 }}><span style={{ fontSize: 11, color: "var(--fg-muted)" }}>Постачальник:</span><SupplierBadge status={s.status} supplierResponse={s.supplierResponse}/></div> : null; })()}
          </div>
          <button onClick={onClose} style={{ width: 32, height: 32, border: 0, background: "transparent", color: "var(--fg-secondary)", borderRadius: 6, cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center" }}>
            <Icon name="x" size={18}/>
          </button>
        </div>

        {/* Scrollable body */}
        <div style={{ flex: 1, overflowY: "auto", padding: 16, display: "flex", flexDirection: "column", gap: 16 }}>

          {/* Status dropdown */}
          <div>
            <Label text="Статус"/>
            <MobileDrop
              open={dropStatus}
              onToggle={() => { setDropStatus(d => !d); setDropPayment(false); }}
              display={<StatusChip status={pendingStatus || order.status}/>}
            >
              {Object.keys(STATUSES).map(s => {
                const active = (pendingStatus || order.status) === s;
                return (
                  <button key={s} onClick={() => { setPendingStatus(s === order.status ? null : s); setDropStatus(false); }} style={{
                    display: "flex", alignItems: "center", justifyContent: "space-between", width: "100%",
                    padding: "9px 10px", border: 0, borderRadius: 8, fontFamily: "inherit",
                    background: active ? "var(--bg-active)" : "transparent", cursor: "pointer",
                  }}>
                    <StatusChip status={s}/>
                    {active && <Icon name="check" size={14} color="var(--accent)"/>}
                  </button>
                );
              })}
            </MobileDrop>
          </div>

          {/* Client + Phone */}
          <div>
            <Label text="Клієнт"/>
            {editName ? (
              <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                <input value={nameVal} onChange={e => setNameVal(e.target.value)} autoFocus
                  style={{ height: 44, padding: "0 14px", background: "var(--bg-raised)", color: "var(--fg-primary)", border: "1px solid var(--accent)", borderRadius: 10, fontSize: 14, fontFamily: "inherit", outline: "none", width: "100%", boxSizing: "border-box" }}/>
                <div style={{ display: "flex", gap: 8 }}>
                  <button onClick={handleSaveName} disabled={savingField === 'name'} style={{ flex: 1, height: 40, background: "var(--accent)", color: "#fff", border: 0, borderRadius: 10, fontSize: 14, cursor: "pointer", fontFamily: "inherit" }}>
                    {savingField === 'name' ? "…" : "Зберегти"}
                  </button>
                  <button onClick={() => setEditName(false)} style={{ height: 40, width: 40, background: "var(--bg-raised)", border: "1px solid var(--border-default)", borderRadius: 10, cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", color: "var(--fg-muted)" }}>
                    <Icon name="x" size={16}/>
                  </button>
                </div>
              </div>
            ) : (
              <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                <span style={{ fontSize: 14, color: "var(--fg-primary)" }}>{order.client}</span>
                {!locked && <button onClick={() => { setNameVal(order.client); setEditName(true); }} style={{ height: 26, padding: "0 10px", background: "transparent", border: "1px solid var(--border-default)", borderRadius: 8, color: "var(--fg-secondary)", fontSize: 12, cursor: "pointer", fontFamily: "inherit" }}>Змінити</button>}
              </div>
            )}
          </div>
          <div>
            <Label text="Телефон"/>
            {editPhone ? (
              <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                <input value={phoneVal} onChange={e => setPhoneVal(e.target.value)} autoFocus
                  style={{ height: 44, padding: "0 14px", background: "var(--bg-raised)", color: "var(--fg-primary)", border: "1px solid var(--accent)", borderRadius: 10, fontSize: 15, fontFamily: "var(--font-mono)", outline: "none", width: "100%", boxSizing: "border-box" }}/>
                <div style={{ display: "flex", gap: 8 }}>
                  <button onClick={handleSavePhone} disabled={savingField === 'phone'} style={{ flex: 1, height: 40, background: "var(--accent)", color: "#fff", border: 0, borderRadius: 10, fontSize: 14, cursor: "pointer", fontFamily: "inherit" }}>
                    {savingField === 'phone' ? "Збереження…" : "Зберегти"}
                  </button>
                  <button onClick={() => setEditPhone(false)} style={{ height: 40, width: 40, background: "var(--bg-raised)", border: "1px solid var(--border-default)", borderRadius: 10, cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", color: "var(--fg-muted)" }}>
                    <Icon name="x" size={16}/>
                  </button>
                </div>
              </div>
            ) : (
              <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                <a href={`tel:${order.phone}`} style={{ fontFamily: "var(--font-mono)", fontSize: 15, color: "var(--fg-primary)", textDecoration: "none" }}>{fmtPhone(order.phone)}</a>
                <div style={{ display: "flex", gap: 6 }}>
                  <MessengerBtn kind="viber"    phone={order.phone}/>
                  <MessengerBtn kind="whatsapp" phone={order.phone}/>
                  <MessengerBtn kind="telegram" phone={order.phone}/>
                </div>
                {!locked && (
                  <button onClick={() => { setPhoneVal(order.phone); setEditPhone(true); }} style={{ height: 28, padding: "0 10px", background: "transparent", border: "1px solid var(--border-default)", borderRadius: 8, color: "var(--fg-secondary)", fontSize: 12, cursor: "pointer", fontFamily: "inherit" }}>
                    Змінити
                  </button>
                )}
              </div>
            )}
          </div>

          {/* Address + Delivery */}
          <div>
            <Label text="Доставка"/>
            <div style={{ display: "flex", flexDirection: "column", gap: 6, alignItems: "flex-start" }}>
              <div style={{ width: "100%", display: "flex", gap: 8, padding: "10px 12px", background: "var(--bg-raised)", border: "1px solid var(--border-default)", borderRadius: 8 }}>
                <Icon name="map-pin" size={16} style={{ marginTop: 2, color: "var(--fg-muted)", flexShrink: 0 }}/>
                <div>
                  {order.delivery && <div style={{ fontSize: 12, color: "var(--fg-muted)", marginBottom: 2 }}>{order.delivery}</div>}
                  <span style={{ fontSize: 13, color: "var(--fg-primary)", lineHeight: 1.45 }}>{order.address || "—"}</span>
                </div>
              </div>
              {!locked && !editDelivery && (
                <button onClick={() => setEditDelivery(true)} style={{ width: "100%", height: 28, padding: "0 10px", background: "transparent", border: "1px solid var(--border-default)", borderRadius: 8, color: "var(--fg-secondary)", fontSize: 12, cursor: "pointer", fontFamily: "inherit" }}>Змінити</button>
              )}
            </div>
            {!locked && editDelivery && (
              <DeliveryEditor
                order={order}
                onFieldChange={onFieldChange}
                onDeliveryTypeSelect={setLocalDeliveryKey}
                onClose={() => setEditDelivery(false)}
              />
            )}
          </div>

          {/* TTN */}
          {order.ttn?.number && (
            <div>
              <Label text="ТТН"/>
              <div style={{ padding: "10px 14px", background: "var(--bg-raised)", border: "1px solid var(--border-default)", borderRadius: 10, display: "flex", flexDirection: "column", gap: 4 }}>
                <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                  <Icon name="package" size={14} style={{ color: "var(--fg-muted)", flexShrink: 0 }}/>
                  <span style={{ fontFamily: "var(--font-mono)", fontSize: 14, fontWeight: 600, color: "var(--fg-primary)" }}>{order.ttn.number}</span>
                  <button onClick={() => copyText(order.ttn.number)} title="Скопіювати ТТН" style={{ height: 24, width: 24, display: "flex", alignItems: "center", justifyContent: "center", background: "transparent", border: "1px solid var(--border-default)", borderRadius: 6, cursor: "pointer", color: "var(--fg-muted)", flexShrink: 0 }}>
                    <Icon name="copy" size={12}/>
                  </button>
                </div>
                {order.ttn.status && <div style={{ fontSize: 13, color: "var(--accent)", paddingLeft: 22 }}>{order.ttn.status}</div>}
                {order.ttn.deliveryDate && <div style={{ fontSize: 12, color: "var(--fg-muted)", paddingLeft: 22 }}>Очікувана доставка: {order.ttn.deliveryDate}</div>}
                {order.ttn.updatedAt && <div style={{ fontSize: 11, color: "var(--fg-muted)", paddingLeft: 22 }}>Оновлено: {order.ttn.updatedAt}</div>}
              </div>
            </div>
          )}

          {/* Payment */}
          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            <Label text="Спосіб оплати"/>
            {locked ? (
              <div style={{ height: 42, padding: "0 14px", display: "flex", alignItems: "center", background: "var(--bg-raised)", border: "1px solid var(--border-default)", borderRadius: 10, fontSize: 14, color: "var(--fg-primary)" }}>
                {localPayment || "—"}
              </div>
            ) : (
            <MobileDrop
              open={dropPayment}
              onToggle={() => { setDropPayment(d => !d); setDropStatus(false); }}
              display={<span style={{ fontSize: 14 }}>{pendingPayment?.label || localPayment || "—"}</span>}
            >
              {PAYMENT_TYPES.filter(pt => !blockedPaymentIds.has(pt.id)).map(pt => {
                const active = pendingPayment?.id === pt.id;
                return (
                  <button key={pt.id} onClick={() => { setPendingPayment(active ? null : pt); setDropPayment(false); }} style={{
                    display: "flex", alignItems: "center", justifyContent: "space-between", width: "100%",
                    padding: "9px 10px", border: 0, borderRadius: 8, fontFamily: "inherit", fontSize: 14,
                    background: active ? "var(--bg-active)" : "transparent",
                    color: "var(--fg-primary)", cursor: "pointer",
                  }}>
                    {pt.label}
                    {active && <Icon name="check" size={14} color="var(--accent)"/>}
                  </button>
                );
              })}
            </MobileDrop>
            )}
            {order.paymentPrice > 0 && (
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "8px 12px", background: "var(--bg-raised)", border: "1px solid var(--border-subtle)", borderRadius: 8 }}>
                <span style={{ fontSize: 12, color: "var(--fg-muted)" }}>Комісія за оплату</span>
                <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--debit)" }}>{fmtMoney(order.paymentPrice)}</span>
              </div>
            )}
          </div>

          {/* Products */}
          <div>
            <Label text="Товари"/>
            <div style={{ background: "var(--bg-raised)", border: "1px solid var(--border-default)", borderRadius: 8, overflow: "hidden" }}>
              {(order.productsRaw.length ? order.productsRaw : []).map((p, i) => (
                <div key={i} style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", padding: "10px 12px", borderBottom: i < order.productsRaw.length - 1 ? "1px solid var(--border-subtle)" : "none", gap: 8 }}>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 13, color: "var(--fg-primary)" }}>{p.title}</div>
                    {p.article && <div style={{ fontSize: 11, color: "var(--fg-muted)", marginTop: 1 }}>Арт: {p.article}</div>}
                  </div>
                  <div style={{ textAlign: "right", flexShrink: 0 }}>
                    <div style={{ fontFamily: "var(--font-mono)", fontSize: 13, fontWeight: 500, color: "var(--fg-primary)" }}>{fmtMoney(p.total_price ?? p.price)}</div>
                    {p.quantity > 1 && <div style={{ fontSize: 11, color: "var(--fg-muted)" }}>{p.quantity} шт</div>}
                  </div>
                </div>
              ))}
            </div>
          </div>

          {/* Totals */}
          <div style={{ display: "flex", flexDirection: "column", gap: 6, paddingTop: 12, borderTop: "1px solid var(--border-subtle)" }}>
            <div style={{ display: "flex", justifyContent: "space-between" }}>
              <span style={{ fontSize: 13, color: "var(--fg-secondary)" }}>Сума товарів</span>
              <span style={{ fontFamily: "var(--font-mono)", fontSize: 13, color: "var(--fg-primary)" }}>{fmtMoney(order.totalDefault)}</span>
            </div>
            {order.paymentPrice > 0 && (
              <div style={{ display: "flex", justifyContent: "space-between" }}>
                <span style={{ fontSize: 13, color: "var(--fg-secondary)" }}>Комісія за оплату</span>
                <span style={{ fontFamily: "var(--font-mono)", fontSize: 13, color: "var(--debit)" }}>+ {fmtMoney(order.paymentPrice)}</span>
              </div>
            )}
            <div style={{ display: "flex", justifyContent: "space-between", paddingTop: 8, borderTop: "1px solid var(--border-subtle)" }}>
              <span style={{ fontSize: 14, fontWeight: 600, color: "var(--fg-primary)" }}>До сплати</span>
              <span style={{ fontFamily: "var(--font-mono)", fontVariantNumeric: "tabular-nums", fontSize: 18, fontWeight: 700, color: "var(--fg-primary)" }}>{fmtMoney(order.totalDefault + order.paymentPrice)}</span>
            </div>
          </div>

          {/* Comments */}
          <div>
            <Label text="Коментарі"/>
            {order.comment && <p style={{ margin: "0 0 8px", fontSize: 13, color: "var(--fg-secondary)", background: "var(--bg-raised)", borderRadius: 8, padding: "10px 12px" }}>{order.comment}</p>}
            <div>
              <div style={{ fontSize: 11, color: "var(--fg-muted)", marginBottom: 6 }}>Коментар менеджера</div>
              <textarea value={commentVal} onChange={e => setCommentVal(e.target.value)}
                placeholder="Додати коментар…" rows={3}
                style={{ width: "100%", boxSizing: "border-box", padding: "10px 12px", background: "var(--bg-raised)", color: "var(--fg-primary)", border: "1px solid var(--border-default)", borderRadius: 10, fontSize: 13, fontFamily: "inherit", resize: "none", outline: "none", lineHeight: 1.5 }}/>
              {commentVal !== (order.managerComment || "") && (
                <div style={{ display: "flex", gap: 8, marginTop: 6 }}>
                  <button onClick={() => setCommentVal(order.managerComment || "")} style={{ flex: 1, height: 36, background: "transparent", border: "1px solid var(--border-default)", borderRadius: 8, color: "var(--fg-secondary)", fontSize: 13, cursor: "pointer", fontFamily: "inherit" }}>Скасувати</button>
                  <button onClick={handleSaveComment} disabled={savingField === 'comment'} style={{ flex: 1, height: 36, background: "var(--accent)", color: "#fff", border: 0, borderRadius: 8, fontSize: 13, cursor: "pointer", fontFamily: "inherit" }}>
                    {savingField === 'comment' ? "…" : "Зберегти"}
                  </button>
                </div>
              )}
            </div>
          </div>

          <OrderCallsSection phone={order.phone}/>
        </div>

        {/* Footer — завжди видимий, з safe-area */}
        <div style={{ padding: 16, paddingBottom: "max(16px, env(safe-area-inset-bottom, 16px))", borderTop: "1px solid var(--border-subtle)", flexShrink: 0 }}>
          <button onClick={handleDone} disabled={saving} style={{
            width: "100%", height: 44, borderRadius: 10, border: 0,
            background: hasPending ? "var(--accent)" : "var(--bg-raised)",
            color: hasPending ? "#fff" : "var(--fg-secondary)",
            fontSize: 14, fontWeight: 500, cursor: saving ? "wait" : "pointer", fontFamily: "inherit",
            transition: "background 150ms, color 150ms",
          }}>
            {saving ? "Збереження…" : "Готово"}
          </button>
        </div>
      </div>
    </div>
  );
}

// ── Main Orders component (desktop + mobile aware) ────────────────
function Orders({ isMobile, showToast }) {
  const [orders, setOrders]         = useState([]);
  const [loading, setLoading]       = useState(true);
  const [error, setError]           = useState(null);
  const [view, setView]             = useState("table");
  const [query, setQuery]           = useState("");
  const [statusFilters, setStatusFilters] = useState(() => {
    try { const s = localStorage.getItem('crm_status_filters'); return s ? JSON.parse(s) : []; } catch { return []; }
  });
  const onToggleStatus = s => {
    const next = statusFilters.includes(s) ? statusFilters.filter(x => x !== s) : [...statusFilters, s];
    setStatusFilters(next);
    try { localStorage.setItem('crm_status_filters', JSON.stringify(next)); } catch {}
  };
  const onClearStatus = () => {
    setStatusFilters([]);
    try { localStorage.removeItem('crm_status_filters'); } catch {}
  };
  const [selected, setSelected]     = useState(null);
  const [kanbanCols, setKanbanCols]       = useState(() => {
    try { const s = localStorage.getItem("crm_kanban_cols"); return s ? JSON.parse(s) : Object.keys(STATUSES); }
    catch { return Object.keys(STATUSES); }
  });
  const [supplierMap, setSupplierMap]     = useState({});

  const handleKanbanCols = (cols) => {
    setKanbanCols(cols);
    localStorage.setItem("crm_kanban_cols", JSON.stringify(cols));
  };

  const fetchOrders = useCallback(async () => {
    setLoading(true); setError(null);
    try {
      const data = await API.getOrders();
      const raw = data.response?.orders || [];
      setOrders(raw.map(mapOrder));
    } catch (e) {
      setError(e.message);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    fetchOrders();
    API.getSupplierStatuses().then(r => setSupplierMap(r.data || {})).catch(() => {});
  }, []);

  const handleStatusChange = (orderId, newStatus) => {
    setOrders(os => os.map(o => o.id === orderId ? { ...o, status: newStatus } : o));
    setSelected(s => s?.id === orderId ? { ...s, status: newStatus } : s);
    showToast("Статус змінено", "success");
  };

  const handlePaymentChange = (orderId, newPaymentLabel, newPaymentPrice) => {
    const upd = o => o.id === orderId
      ? { ...o, payment: newPaymentLabel, ...(newPaymentPrice !== undefined ? { paymentPrice: newPaymentPrice, total: o.totalDefault + newPaymentPrice } : {}) }
      : o;
    setOrders(os => os.map(upd));
    setSelected(s => s?.id === orderId ? upd(s) : s);
    showToast("Спосіб оплати змінено", "success");
  };

  const handlePhoneChange = (orderId, newPhone) => {
    setOrders(os => os.map(o => o.id === orderId ? { ...o, phone: newPhone } : o));
    setSelected(s => s?.id === orderId ? { ...s, phone: newPhone } : s);
    showToast("Телефон змінено", "success");
  };

  const handleFieldChange = (orderId, patch) => {
    setOrders(os => os.map(o => o.id === orderId ? { ...o, ...patch } : o));
    setSelected(s => s?.id === orderId ? { ...s, ...patch } : s);
    showToast("Збережено", "success");
  };

  const filtered = orders.filter(o => {
    if (statusFilters.length > 0 && !statusFilters.includes(o.status)) return false;
    if (query) {
      const q = query.toLowerCase();
      const qDigits = query.replace(/\D/g, "");
      const phoneDigits = (o.phone || "").replace(/\D/g, "");
      const textMatch = `${o.id} ${o.client} ${o.phone} ${o.address}`.toLowerCase().includes(q);
      const digitMatch = qDigits.length >= 3 && phoneDigits.includes(qDigits);
      if (!textMatch && !digitMatch) return false;
    }
    return true;
  });

  if (loading) return (
    <div style={{ flex: 1, display: "flex", flexDirection: "column" }}>
      <SkeletonRows n={10}/>
    </div>
  );
  if (error) return (
    <EmptyState icon="wifi-off" message={`Не вдалося завантажити: ${error}`} action={
      <Button variant="secondary" size="sm" leftIcon="refresh-cw" onClick={fetchOrders}>Повторити</Button>
    }/>
  );

  // ── Mobile layout ──────────────────────────────────────────────
  if (isMobile) {
    return (
      <>
        <div style={{ display: "flex", gap: 8, padding: "10px 16px 4px", flexShrink: 0 }}>
          <div style={{ position: "relative", flex: 1 }}>
            <Icon name="search" size={14} style={{ position: "absolute", left: 12, top: "50%", transform: "translateY(-50%)", color: "var(--fg-muted)" }}/>
            <input value={query} onChange={e => setQuery(e.target.value)} placeholder="Пошук за номером, клієнтом…" style={{
              width: "100%", height: 36, boxSizing: "border-box", padding: "0 12px 0 34px",
              background: "var(--bg-panel)", color: "var(--fg-primary)",
              border: "1px solid var(--border-default)", borderRadius: 8, fontSize: 13, outline: "none", fontFamily: "inherit",
            }}/>
          </div>
          <button onClick={fetchOrders} title="Оновити" style={{
            width: 36, height: 36, flexShrink: 0, border: "1px solid var(--border-default)",
            borderRadius: 8, background: "var(--bg-panel)", color: "var(--fg-secondary)",
            display: "flex", alignItems: "center", justifyContent: "center", cursor: "pointer",
          }}>
            <Icon name="refresh-cw" size={15}/>
          </button>
        </div>
        <MobileStatusFilters
          active={statusFilters.length === 1 ? statusFilters[0] : "all"}
          onChange={s => {
            if (s === "all") onClearStatus();
            else { setStatusFilters([s]); try { localStorage.setItem('crm_status_filters', JSON.stringify([s])); } catch {} }
          }}
          orders={orders}
        />
        <div style={{ flex: 1, overflowY: "auto", padding: "12px 16px", display: "flex", flexDirection: "column", gap: 10 }}>
          {filtered.length === 0
            ? <div style={{ padding: "40px 20px", textAlign: "center", color: "var(--fg-muted)", fontSize: 13 }}>Замовлень не знайдено</div>
            : filtered.map(o => <OrderCardMobile key={o.id} o={o} onOpen={setSelected} supplierInfo={supplierMap[String(o.id)]}/>)
          }
        </div>
        {selected && <OrderDetailSheetMobile order={selected} onClose={() => setSelected(null)} onStatusChange={handleStatusChange} onPaymentChange={handlePaymentChange} onPhoneChange={handlePhoneChange} onFieldChange={handleFieldChange} supplierMap={supplierMap}/>}
      </>
    );
  }

  // ── Desktop layout ─────────────────────────────────────────────
  return (
    <div style={{ flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" }}>
      <FilterBar view={view} onView={setView} query={query} onQuery={setQuery} statusFilters={statusFilters} onToggleStatus={onToggleStatus} onClearStatus={onClearStatus} orders={orders} onRefresh={fetchOrders} kanbanCols={kanbanCols} onKanbanCols={handleKanbanCols}/>
      <div style={{ flex: 1, display: "flex", overflow: "hidden", position: "relative" }}>
        <div style={{ flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" }}>
          {view === "table"
            ? <OrderTable orders={filtered} onSelect={setSelected} selectedId={selected?.id} supplierMap={supplierMap}/>
            : <OrderKanban orders={filtered} onSelect={setSelected} visibleCols={kanbanCols} supplierMap={supplierMap}/>
          }
        </div>
        {selected && <OrderDetail order={selected} onClose={() => setSelected(null)} onStatusChange={handleStatusChange} onPaymentChange={handlePaymentChange} onPhoneChange={handlePhoneChange} onFieldChange={handleFieldChange} supplierMap={supplierMap}/>}
      </div>
    </div>
  );
}

window.Orders = Orders;
