/* Estoque de Sorvetes — controle por armazém, com transferências e registro append-only */

const MOVEMENT_LABELS = {
  "seed":          { label: "Saldo inicial", tone: "neutral" },
  "produce":       { label: "Produção",      tone: "success" },
  "sale":          { label: "Venda",         tone: "info" },
  "saida":         { label: "Saída picolezeiro", tone: "warning" },
  "retorno":       { label: "Retorno",       tone: "info" },
  "cancel-saida":  { label: "Saída cancelada", tone: "neutral" },
  "adjust":        { label: "Ajuste manual", tone: "neutral" },
  "transfer-out":  { label: "Transferência (saída)", tone: "warning" },
  "transfer-in":   { label: "Transferência (entrada)", tone: "success" },
};

function Estoque({ ctx }) {
  const warehouses = ctx.state.warehouses;
  const [sub, setSub] = useState("geral");
  const [view, setView] = useState("grid");
  const [filterLine, setFilterLine] = useState("all");
  const [editing, setEditing] = useState(null);
  const [adjusting, setAdjusting] = useState(null);
  const [transferring, setTransferring] = useState(null);

  const items = [
    { value: "geral", label: "Visão geral" },
    ...warehouses.map(w => ({ value: w.id, label: w.name })),
    { value: "log",   label: "Movimentações" },
  ];

  return (
    <>
      <div className="page-head">
        <div>
          <h1>Estoque de Sorvetes</h1>
          <p>Controle por armazém, validade, transferências e histórico de movimentações</p>
        </div>
        <div className="page-head__actions">
          <Button variant="secondary" icon={<Icons.ArrowUp size={14} strokeWidth={2.2} style={{ transform:"rotate(90deg)" }}/>} onClick={() => setTransferring({})}>Transferir</Button>
          <Button variant="primary" icon={<Icons.Plus size={14} strokeWidth={2.2}/>} onClick={() => setAdjusting("new")}>Ajuste de estoque</Button>
        </div>
      </div>

      <Tabs items={items} value={sub} onChange={setSub} />

      {sub === "geral" && (
        <GeralView ctx={ctx} onGoTo={setSub} />
      )}
      {sub === "log"   && <MovimentacoesLog ctx={ctx} />}
      {warehouses.some(w => w.id === sub) && (
        <WarehouseView
          ctx={ctx}
          warehouse={warehouses.find(w => w.id === sub)}
          view={view} setView={setView}
          filterLine={filterLine} setFilterLine={setFilterLine}
          onEdit={setEditing}
          onAdjust={(payload) => setAdjusting(payload)}
          onTransfer={(payload) => setTransferring(payload)}
        />
      )}

      {editing && <StockEditModal ctx={ctx} item={editing} onClose={() => setEditing(null)} />}
      {adjusting && <AjusteEstoqueModal ctx={ctx} initial={typeof adjusting === "object" ? adjusting : null} onClose={() => setAdjusting(null)} />}
      {transferring && <TransferirModal ctx={ctx} initial={transferring} onClose={() => setTransferring(null)} />}
    </>
  );
}

/* ============ Visão geral — consolidado (TOTAL de todos os armazéns) ============ */
function GeralView({ ctx, onGoTo }) {
  const today = new Date("2026-05-20");
  const totalUnits = ctx.state.stock.reduce((s, x) => s + x.units, 0);
  const totalValue = ctx.state.stock.reduce((s, x) => {
    const p = ctx.state.products.find(p => p.id === x.productId);
    return s + x.units * (p?.price || 0);
  }, 0);
  const critical = ctx.state.stock.filter(s => s.units < s.minUnits).length;
  const expiringSoon = ctx.state.stock.filter(s => {
    const days = (new Date(s.expiresOn) - today) / (1000*60*60*24);
    return days < 60;
  }).length;

  // Tabela consolidada: 1 linha por produto, somando unidades de TODOS os armazéns
  const perProduct = ctx.state.products.map(p => {
    const rows = ctx.state.stock.filter(s => s.productId === p.id);
    const units = rows.reduce((sm, r) => sm + r.units, 0);
    const perWh = ctx.state.warehouses.map(w => {
      const r = rows.find(x => x.warehouseId === w.id);
      return { wh: w, units: r?.units || 0 };
    });
    const minTotal = rows.reduce((sm, r) => sm + r.minUnits, 0);
    return { product: p, units, perWh, minTotal, value: units * (p.price || 0) };
  }).filter(x => x.units > 0).sort((a,b) => b.units - a.units);

  return (
    <>
      <div className="grid-4" style={{ marginBottom: 14 }}>
        <KPI tone="info"    medal={<Icons.Box size={18} strokeWidth={2}/>}            label="Total em estoque"           value={fmtInt(totalUnits)} sub="Unidades em todos os armazéns" />
        <KPI tone="success" medal={<Icons.Wallet size={18} strokeWidth={2}/>}         label="Valor estocado"             value={fmtBRL(totalValue)} sub="A preço de varejo" />
        <KPI tone="danger"  medal={<Icons.AlertTriangle size={18} strokeWidth={2}/>}  label="Itens abaixo do mínimo"     value={critical+""}        sub={`Em ${ctx.state.warehouses.length} armazéns`} />
        <KPI tone="warning" medal={<Icons.Calendar size={18} strokeWidth={2}/>}       label="Validade próxima"           value={expiringSoon+""}    sub="Em até 60 dias" />
      </div>

      <div className="grid-2" style={{ gap: 14, marginBottom: 14 }}>
        {ctx.state.warehouses.map(w => {
          const rows = ctx.state.stock.filter(s => s.warehouseId === w.id);
          const units = rows.reduce((sm, r) => sm + r.units, 0);
          const value = rows.reduce((sm, r) => {
            const p = ctx.state.products.find(p => p.id === r.productId);
            return sm + r.units * (p?.price || 0);
          }, 0);
          const low = rows.filter(r => r.units < r.minUnits).length;
          return (
            <Card key={w.id}
              title={w.name}
              subtitle={w.note || (w.system ? "Armazém do sistema" : "Armazém customizado")}
              action={<Button variant="secondary" size="sm" icon={<Icons.ArrowUp size={12} style={{ transform:"rotate(90deg)" }}/>} onClick={() => onGoTo(w.id)}>Ver detalhe</Button>}
            >
              <div style={{ display:"flex", gap:24, padding:"4px 0" }}>
                <div>
                  <div className="muted" style={{ fontSize:12 }}>Unidades</div>
                  <div className="numeric" style={{ fontFamily:"var(--font-display)", fontSize:28, fontWeight:700, color:"var(--ink-900)" }}>{fmtInt(units)}</div>
                </div>
                <div>
                  <div className="muted" style={{ fontSize:12 }}>Valor</div>
                  <div className="numeric" style={{ fontFamily:"var(--font-display)", fontSize:28, fontWeight:700, color:"var(--ink-900)" }}>{fmtBRL(value)}</div>
                </div>
                <div>
                  <div className="muted" style={{ fontSize:12 }}>Sabores</div>
                  <div className="numeric" style={{ fontFamily:"var(--font-display)", fontSize:28, fontWeight:700, color:"var(--ink-900)" }}>{rows.filter(r => r.units > 0).length}</div>
                </div>
                <div>
                  <div className="muted" style={{ fontSize:12 }}>Críticos</div>
                  <div className="numeric" style={{ fontFamily:"var(--font-display)", fontSize:28, fontWeight:700, color: low ? "var(--danger)" : "var(--ink-900)" }}>{low}</div>
                </div>
              </div>
            </Card>
          );
        })}
      </div>

      <Card title="Estoque total por sabor" subtitle="Consolidado de todos os armazéns. Para ver/editar por armazém, use as abas acima." flush style={{ marginBottom: 14 }}>
        {perProduct.length === 0 ? (
          <div className="empty">
            <Icons.Box size={26} color="var(--ink-300)"/>
            <h4>Sem estoque</h4>
            <p>Quando houver produção ou ajuste, o consolidado aparece aqui.</p>
          </div>
        ) : (
          <table className="tbl">
            <thead>
              <tr>
                <th>Sabor</th>
                <th>Linha</th>
                {ctx.state.warehouses.map(w => (
                  <th key={w.id} className="num">{w.name}</th>
                ))}
                <th className="num">Total</th>
                <th className="num">Valor</th>
              </tr>
            </thead>
            <tbody>
              {perProduct.map(x => (
                <tr key={x.product.id}>
                  <td><FlavorTagX product={x.product} /></td>
                  <td className="muted">{x.product.line}</td>
                  {x.perWh.map(({ wh, units }) => (
                    <td key={wh.id} className="num numeric" style={{ color: units === 0 ? "var(--ink-400)" : "var(--ink-700)" }}>{units}</td>
                  ))}
                  <td className="num strong numeric">{x.units}</td>
                  <td className="num numeric muted">{fmtBRL(x.value)}</td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </Card>

      <Card title="Movimentações recentes" subtitle="Últimas 12 movimentações em todos os armazéns — registro permanente, não editável" flush>
        <MovimentacoesTable ctx={ctx} limit={12} />
      </Card>
    </>
  );
}

/* ============ Visão por armazém ============ */
function WarehouseView({ ctx, warehouse, view, setView, filterLine, setFilterLine, onEdit, onAdjust, onTransfer }) {
  const today = new Date("2026-05-20");
  const allInWh = ctx.state.stock.filter(s => s.warehouseId === warehouse.id);
  const totalUnits = allInWh.reduce((s, x) => s + x.units, 0);
  const totalValue = allInWh.reduce((s, x) => {
    const p = ctx.state.products.find(p => p.id === x.productId);
    return s + x.units * (p?.price || 0);
  }, 0);
  const critical = allInWh.filter(s => s.units < s.minUnits).length;
  const expiringSoon = allInWh.filter(s => {
    const days = (new Date(s.expiresOn) - today) / (1000*60*60*24);
    return days < 60;
  }).length;

  return (
    <>
      <div className="grid-4" style={{ marginBottom: 14 }}>
        <KPI tone="info" medal={<Icons.Box size={18} strokeWidth={2}/>} label={`${warehouse.name} · estoque`} value={fmtInt(totalUnits)} sub="Unidades" />
        <KPI tone="success" medal={<Icons.Wallet size={18} strokeWidth={2}/>} label="Valor estocado" value={fmtBRL(totalValue)} sub="A preço de varejo" />
        <KPI tone="danger" medal={<Icons.AlertTriangle size={18} strokeWidth={2}/>} label="Sabores abaixo do mínimo" value={critical+""} sub="Itens críticos" />
        <KPI tone="warning" medal={<Icons.Calendar size={18} strokeWidth={2}/>} label="Validade próxima" value={expiringSoon+""} sub="Em até 60 dias" />
      </div>

      <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center", marginBottom:14 }}>
        <Segmented
          options={[
            { value:"all", label:"Todos" },
            { value:"Picolé", label:"Picolés" },
            { value:"Paleta Silver", label:"Silver" },
            { value:"Paleta Gold", label:"Gold" },
          ]}
          value={filterLine}
          onChange={setFilterLine}
        />
        <Segmented
          options={[
            { value:"grid", label:"Grade" },
            { value:"table", label:"Tabela" },
          ]}
          value={view}
          onChange={setView}
        />
      </div>

      <StockItemsDisplay
        ctx={ctx} warehouse={warehouse}
        items={allInWh}
        view={view} filterLine={filterLine}
        onEdit={onEdit} onAdjust={onAdjust} onTransfer={onTransfer}
        emptyMessage={`Nenhum sabor em ${warehouse.name}. Use "Transferir" para mover unidades de outro armazém ou registre uma produção destinada a este armazém.`}
      />

      <div style={{ height: 14 }} />
      <Card title={`Movimentações · ${warehouse.name}`} subtitle="Registro permanente das entradas e saídas deste armazém (não editável)" flush>
        <MovimentacoesTable ctx={ctx} warehouseId={warehouse.id} limit={50} />
      </Card>
    </>
  );
}

/* ============ Grade/tabela de produtos de UM armazém — reutilizado em Geral e por armazém ============ */
function StockItemsDisplay({ ctx, warehouse, items, view, filterLine, onEdit, onAdjust, onTransfer, emptyMessage }) {
  const today = new Date("2026-05-20");
  const filtered = items.filter(s => {
    const p = ctx.state.products.find(p => p.id === s.productId);
    if (!p) return false;
    if (filterLine === "all") return true;
    return p.line === filterLine;
  });

  if (filtered.length === 0) {
    return (
      <Card><div className="empty">
        <Icons.Box size={26} color="var(--ink-300)"/>
        <h4>Sem itens</h4>
        <p>{emptyMessage || "Nenhum sabor para os filtros atuais."}</p>
      </div></Card>
    );
  }

  if (view === "grid") {
    return (
      <div className="grid-4" style={{ gap: 14 }}>
        {filtered.map(s => {
          const p = ctx.state.products.find(p => p.id === s.productId);
          if (!p) return null;
          const days = Math.floor((new Date(s.expiresOn) - today) / (1000*60*60*24));
          const low = s.units < s.minUnits;
          return (
            <div key={warehouse.id + "-" + s.productId} style={{ background:"white", border:"1px solid var(--line)", borderRadius:10, overflow:"hidden", display:"flex", flexDirection:"column", position:"relative" }}>
              <div style={{ height: 6, background: p.color }} />
              <div style={{ padding: 14, display:"flex", flexDirection:"column", gap:10 }}>
                <div style={{ display:"flex", justifyContent:"space-between", alignItems:"flex-start", gap:8 }}>
                  <div style={{ minWidth:0 }}>
                    <div style={{ fontSize:11, color:"var(--ink-400)", fontWeight:600, textTransform:"uppercase", letterSpacing:".06em" }}>{p.line}</div>
                    <div style={{ fontWeight:700, color:"var(--ink-900)", fontSize:14 }}>{p.flavor}</div>
                  </div>
                  {low && <Chip tone="danger" dot>baixo</Chip>}
                </div>
                <div className="numeric" style={{ fontFamily:"var(--font-display)", fontSize:32, fontWeight:700, color:"var(--ink-900)", letterSpacing:"-.025em", lineHeight:1 }}>
                  {s.units} <span style={{ fontSize:14, color:"var(--ink-400)", fontWeight:500 }}>un</span>
                </div>
                <ProgressBar value={Math.min(s.units, s.minUnits*2 || 1)} max={s.minUnits*2 || 1} tone={low ? "danger" : (s.units < s.minUnits*1.5 ? "warn" : "ok")} />
                <div style={{ display:"flex", justifyContent:"space-between", fontSize:11.5, color:"var(--ink-500)" }}>
                  <span>min. {s.minUnits} un</span>
                  <span>≈ {Math.ceil(s.units / Math.max(1, s.perBox))} caixas</span>
                </div>
                <div style={{ display:"flex", justifyContent:"space-between", paddingTop:10, borderTop:"1px solid var(--line)", fontSize:11.5 }}>
                  <span className="muted">Validade</span>
                  <span style={{ color: days < 60 ? "var(--warning)" : "var(--ink-700)", fontWeight:500 }}>{fmtDate(s.expiresOn)} · {days}d</span>
                </div>
                <div style={{ display:"flex", gap:4, marginTop:4 }}>
                  <Button variant="secondary" size="sm" icon={<Icons.Plus size={12}/>} onClick={() => onAdjust({ productId: s.productId, warehouseId: warehouse.id, kind:"in" })} style={{ flex:1, justifyContent:"center" }}>Entrada</Button>
                  <Button variant="secondary" size="sm" icon={<Icons.Minus size={12}/>} onClick={() => onAdjust({ productId: s.productId, warehouseId: warehouse.id, kind:"out" })} style={{ flex:1, justifyContent:"center" }}>Baixa</Button>
                  <button className="icon-btn" title="Transferir para outro armazém" onClick={() => onTransfer({ productId: s.productId, fromWh: warehouse.id })}>
                    <Icons.ArrowUp size={14} style={{ transform:"rotate(90deg)" }}/>
                  </button>
                  <button className="icon-btn" title="Configurar mínimo" onClick={() => onEdit({ ...s })}><Icons.Edit /></button>
                </div>
              </div>
            </div>
          );
        })}
      </div>
    );
  }

  return (
    <Card flush>
      <table className="tbl">
        <thead>
          <tr>
            <th>Produto</th>
            <th>Linha</th>
            <th className="num">Unidades</th>
            <th className="num">Caixas</th>
            <th>Nível</th>
            <th className="num">Mínimo</th>
            <th>Fabricado em</th>
            <th>Vence em</th>
            <th></th>
            <th></th>
          </tr>
        </thead>
        <tbody>
          {filtered.map(s => {
            const p = ctx.state.products.find(p => p.id === s.productId);
            if (!p) return null;
            const days = Math.floor((new Date(s.expiresOn) - today) / (1000*60*60*24));
            const low = s.units < s.minUnits;
            return (
              <tr key={warehouse.id + "-" + s.productId}>
                <td><FlavorTagX product={p} /></td>
                <td className="muted">{p.line}</td>
                <td className="num strong numeric">{s.units}</td>
                <td className="num numeric muted">{Math.ceil(s.units / Math.max(1, s.perBox))}</td>
                <td style={{ width:140 }}><ProgressBar value={Math.min(s.units, s.minUnits*2 || 1)} max={s.minUnits*2 || 1} tone={low ? "danger" : (s.units < s.minUnits*1.5 ? "warn" : "ok")} /></td>
                <td className="num muted">{s.minUnits}</td>
                <td className="muted">{fmtDate(s.producedOn)}</td>
                <td style={{ color: days < 60 ? "var(--warning)" : "var(--ink-700)" }}>{fmtDate(s.expiresOn)}</td>
                <td>{low ? <Chip tone="danger" dot>baixo</Chip> : days < 60 ? <Chip tone="warning" dot>vence</Chip> : <Chip tone="success" dot>ok</Chip>}</td>
                <td>
                  <div style={{ display:"flex", gap:2 }}>
                    <button className="icon-btn" title="Ajustar" onClick={() => onAdjust({ productId: s.productId, warehouseId: warehouse.id })}><Icons.Plus /></button>
                    <button className="icon-btn" title="Transferir" onClick={() => onTransfer({ productId: s.productId, fromWh: warehouse.id })}>
                      <Icons.ArrowUp size={14} style={{ transform:"rotate(90deg)" }}/>
                    </button>
                    <button className="icon-btn" title="Configurações" onClick={() => onEdit({ ...s })}><Icons.Edit /></button>
                  </div>
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </Card>
  );
}

/* ============ Página de Movimentações (geral) ============ */
function MovimentacoesLog({ ctx }) {
  const [whFilter, setWhFilter] = useState("all");
  const [kindFilter, setKindFilter] = useState("all");

  const whOptions = [{ value:"all", label:"Todos os armazéns" }, ...ctx.state.warehouses.map(w => ({ value:w.id, label:w.name }))];
  const kindOptions = [{ value:"all", label:"Todos os tipos" },
    ...Object.entries(MOVEMENT_LABELS).map(([k, v]) => ({ value: k, label: v.label }))];

  return (
    <>
      <Card title="Registro geral de movimentações" subtitle="Tudo o que entrou e saiu de todos os armazéns. Registro permanente — não pode ser editado." flush>
        <div style={{ padding: "12px 14px", display:"flex", gap: 10, borderBottom: "1px solid var(--line)" }}>
          <select className="select" value={whFilter} onChange={e => setWhFilter(e.target.value)} style={{ maxWidth: 220 }}>
            {whOptions.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
          </select>
          <select className="select" value={kindFilter} onChange={e => setKindFilter(e.target.value)} style={{ maxWidth: 240 }}>
            {kindOptions.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
          </select>
        </div>
        <MovimentacoesTable ctx={ctx} warehouseId={whFilter === "all" ? null : whFilter} kind={kindFilter === "all" ? null : kindFilter} limit={500} />
      </Card>
    </>
  );
}

function MovimentacoesTable({ ctx, warehouseId, kind, limit }) {
  let rows = ctx.state.stockMovements;
  if (warehouseId) rows = rows.filter(m => m.warehouseId === warehouseId);
  if (kind)        rows = rows.filter(m => m.kind === kind);
  rows = rows.slice().sort((a,b) => (b.ts || "").localeCompare(a.ts || "")).slice(0, limit || 100);

  if (rows.length === 0) {
    return <div className="empty">
      <Icons.Box size={26} color="var(--ink-300)"/>
      <h4>Sem movimentações</h4>
      <p>Quando houver produções, vendas, saídas, retornos ou ajustes, eles aparecerão aqui.</p>
    </div>;
  }

  return (
    <table className="tbl">
      <thead>
        <tr>
          <th>Data/Hora</th>
          <th>Armazém</th>
          <th>Produto</th>
          <th>Tipo</th>
          <th className="num">Unidades</th>
          <th>Referência</th>
        </tr>
      </thead>
      <tbody>
        {rows.map(m => {
          const w = ctx.state.warehouses.find(x => x.id === m.warehouseId);
          const p = ctx.state.products.find(x => x.id === m.productId);
          const counter = m.counterpartWarehouseId ? ctx.state.warehouses.find(x => x.id === m.counterpartWarehouseId) : null;
          const meta = MOVEMENT_LABELS[m.kind] || { label: m.kind, tone: "neutral" };
          const positive = m.units > 0;
          return (
            <tr key={m.id}>
              <td className="muted">{fmtDateTime(m.ts)}</td>
              <td>{w?.name || "—"}</td>
              <td>{p ? <FlavorTagX product={p} /> : "—"}</td>
              <td><Chip tone={meta.tone} dot>{meta.label}</Chip></td>
              <td className="num strong numeric" style={{ color: positive ? "var(--success)" : "var(--danger)" }}>
                {positive ? "+" : ""}{m.units}
              </td>
              <td className="muted" style={{ fontSize:12 }}>
                {counter ? `↔ ${counter.name}` : ""}
                {counter && m.note ? " · " : ""}
                {m.note || (counter ? "" : "—")}
              </td>
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}

/* ============ Modais ============ */
function StockEditModal({ ctx, item, onClose }) {
  const p = ctx.state.products.find(p => p.id === item.productId);
  const w = ctx.state.warehouses.find(x => x.id === item.warehouseId);
  const [min, setMin] = useState(String(item.minUnits));
  const submit = () => {
    ctx.actions.setStockMin(item.productId, parseInt(min || "0", 10), item.warehouseId);
    onClose();
  };
  return (
    <Modal title={`Configurações · ${p?.flavor}`} subtitle={w?.name} onClose={onClose}
      footer={<><Button variant="ghost" onClick={onClose}>Cancelar</Button><Button variant="primary" onClick={submit}>Salvar</Button></>}
    >
      <div className="grid-2" style={{ gap:14 }}>
        <Field label="Estoque mínimo (unidades)" hint="Alerta quando o estoque cair abaixo deste valor neste armazém">
          <input className="input numeric" value={min} onChange={e => setMin(e.target.value.replace(/\D/g,""))} autoFocus />
        </Field>
        <Field label="Estoque atual"><input className="input" value={item.units + " un"} readOnly /></Field>
      </div>
    </Modal>
  );
}

function AjusteEstoqueModal({ ctx, initial, onClose }) {
  const [productId, setProductId] = useState(initial?.productId || ctx.state.products[0]?.id || "");
  const [warehouseId, setWarehouseId] = useState(initial?.warehouseId || ctx.state.warehouses[0]?.id || "");
  const [kind, setKind] = useState(initial?.kind || "in");
  const [qty, setQty] = useState("");
  const [reason, setReason] = useState("");
  const [err, setErr] = useState({});

  const submit = () => {
    const n = parseInt(qty, 10);
    const e = {};
    if (!productId)   e.productId = "Selecione o sabor";
    if (!warehouseId) e.warehouseId = "Selecione o armazém";
    if (!n || n <= 0) e.qty = "Quantidade inválida";
    setErr(e);
    if (Object.keys(e).length) return;
    ctx.actions.adjustStock(productId, kind === "in" ? n : -n, warehouseId, { reason });
    ctx.pushToast(`Ajuste registrado · ${kind === "in" ? "+" : "−"}${n} un`);
    onClose();
  };

  return (
    <Modal title="Ajuste manual de estoque" onClose={onClose}
      footer={<><Button variant="ghost" onClick={onClose}>Cancelar</Button><Button variant="primary" onClick={submit}>Registrar ajuste</Button></>}
    >
      <Segmented options={[{value:"in", label:"Entrada (+)"},{value:"out", label:"Baixa (−)"}]} value={kind} onChange={setKind} />
      <div style={{ height:14 }} />
      <div className="grid-2" style={{ gap:14 }}>
        <Field label="Armazém" required error={err.warehouseId}>
          <select className="select" value={warehouseId} onChange={e => setWarehouseId(e.target.value)}>
            {ctx.state.warehouses.map(w => <option key={w.id} value={w.id}>{w.name}</option>)}
          </select>
        </Field>
        <Field label="Produto" required error={err.productId}>
          <select className="select" value={productId} onChange={e => setProductId(e.target.value)}>
            {ctx.state.products.map(p => <option key={p.id} value={p.id}>{p.line} — {p.flavor}</option>)}
          </select>
        </Field>
        <Field label="Quantidade (unidades)" required error={err.qty}>
          <input className="input numeric" value={qty} onChange={e => setQty(e.target.value.replace(/\D/g,""))} placeholder="0" autoFocus />
        </Field>
        <Field label="Motivo" hint="Para fins de auditoria">
          <select className="select" value={reason} onChange={e => setReason(e.target.value)}>
            <option value="">—</option>
            <option>Inventário</option>
            <option>Perda</option>
            <option>Quebra/avaria</option>
            <option>Doação</option>
            <option>Outro</option>
          </select>
        </Field>
      </div>
    </Modal>
  );
}

function TransferirModal({ ctx, initial, onClose }) {
  const whs = ctx.state.warehouses;
  const [fromWh, setFromWh] = useState(initial?.fromWh || whs[0]?.id || "");
  const [toWh, setToWh] = useState(initial?.toWh || whs.find(w => w.id !== (initial?.fromWh || whs[0]?.id))?.id || "");
  const [productId, setProductId] = useState(initial?.productId || ctx.state.products[0]?.id || "");
  const [qty, setQty] = useState("");
  const [note, setNote] = useState("");
  const [err, setErr] = useState({});

  const fromRow = ctx.state.stock.find(x => x.warehouseId === fromWh && x.productId === productId);
  const available = fromRow?.units || 0;

  const submit = () => {
    const n = parseInt(qty, 10);
    const e = {};
    if (!fromWh) e.fromWh = "Selecione a origem";
    if (!toWh)   e.toWh   = "Selecione o destino";
    if (fromWh === toWh) e.toWh = "Origem e destino devem ser diferentes";
    if (!productId) e.productId = "Selecione o sabor";
    if (!n || n <= 0) e.qty = "Quantidade inválida";
    else if (n > available) e.qty = `Disponível: ${available} un`;
    setErr(e);
    if (Object.keys(e).length) return;
    ctx.actions.transferStock({ fromWh, toWh, productId, units: n, note });
    onClose();
  };

  return (
    <Modal title="Transferir entre armazéns" onClose={onClose}
      footer={<><Button variant="ghost" onClick={onClose}>Cancelar</Button><Button variant="primary" onClick={submit}>Transferir</Button></>}
    >
      <div className="grid-2" style={{ gap:14 }}>
        <Field label="Origem" required error={err.fromWh}>
          <select className="select" value={fromWh} onChange={e => setFromWh(e.target.value)}>
            {whs.map(w => <option key={w.id} value={w.id}>{w.name}</option>)}
          </select>
        </Field>
        <Field label="Destino" required error={err.toWh}>
          <select className="select" value={toWh} onChange={e => setToWh(e.target.value)}>
            {whs.map(w => <option key={w.id} value={w.id}>{w.name}</option>)}
          </select>
        </Field>
        <Field label="Produto" required error={err.productId} style={{ gridColumn:"span 2" }}>
          <select className="select" value={productId} onChange={e => setProductId(e.target.value)}>
            {ctx.state.products.map(p => <option key={p.id} value={p.id}>{p.line} — {p.flavor}</option>)}
          </select>
        </Field>
        <Field label={`Quantidade (disponível: ${available} un)`} required error={err.qty}>
          <input className="input numeric" value={qty} onChange={e => setQty(e.target.value.replace(/\D/g,""))} placeholder="0" autoFocus />
        </Field>
        <Field label="Observação" hint="Opcional">
          <input className="input" value={note} onChange={e => setNote(e.target.value)} placeholder="Ex.: abastecimento semanal" />
        </Field>
      </div>
    </Modal>
  );
}

function FlavorTagX({ product }) {
  return (
    <span className="tag-flavor">
      <span className="sw" style={{ background: product.color }} />
      {product.flavor}
    </span>
  );
}

window.Estoque = Estoque;
