/* ============================================================
   PCP — Forms: Modal system + add/new flows
   (shares global scope; useState etc. come from ui.jsx)
   ============================================================ */

function Modal({ size = "md", icon, title, sub, onClose, footer, children }) {
  useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [onClose]);
  return (
    <div className="modal-scrim" onMouseDown={onClose}>
      <div className={"modal " + size} onMouseDown={(e) => e.stopPropagation()}>
        <div className="modal-head">
          {icon && <span className="m-ic"><Icon name={icon} size={18} /></span>}
          <div className="grow" style={{ minWidth: 0 }}>
            <h2>{title}</h2>
            {sub && <div className="sub">{sub}</div>}
          </div>
          <span className="spacer" />
          <IconBtn icon="x" onClick={onClose} title="Fechar (Esc)" />
        </div>
        <div className="modal-body">{children}</div>
        {footer && <div className="modal-foot">{footer}</div>}
      </div>
    </div>
  );
}

function Field({ label, req, opt, help, children }) {
  return (
    <div className="field">
      {label && <label className="lbl">{label}{req && <span className="req">*</span>}{opt && <span className="opt">opcional</span>}</label>}
      {children}
      {help && <div className="help">{help}</div>}
    </div>
  );
}

function Choice({ value, options, onChange }) {
  return (
    <div className="choice">
      {options.map((o) => {
        const val = o.v ?? o;
        const lbl = o.l ?? o;
        return <button key={val} type="button" className={value === val ? "on" : ""} onClick={() => onChange(val)}>
          {o.dot && <span className="dotc" />}{lbl}
        </button>;
      })}
    </div>
  );
}

function PrioScale({ value, onChange }) {
  return (
    <div className="prio-scale">
      {[0,1,2,3,4,5,6,7,8,9].map((n) => (
        <button key={n} type="button" className={value === n ? "on" : ""} onClick={() => onChange(n)}>{n}</button>
      ))}
    </div>
  );
}

function Autocomplete({ items, value, onChange, placeholder, render }) {
  const [open, setOpen] = useState(false);
  const [q, setQ] = useState(value || "");
  useEffect(() => { setQ(value || ""); }, [value]);
  const filtered = items.filter((i) => (i.nome || i).toLowerCase().includes(q.toLowerCase())).slice(0, 6);
  return (
    <div className="ac">
      <div className="fld-wrap">
        <Icon name="search" size={15} className="ico-in" />
        <input className="fld" value={q} placeholder={placeholder}
          onChange={(e) => { setQ(e.target.value); onChange(e.target.value); setOpen(true); }}
          onFocus={() => setOpen(true)} onBlur={() => setTimeout(() => setOpen(false), 150)} />
      </div>
      {open && filtered.length > 0 && (
        <div className="ac-list">
          {filtered.map((i, k) => (
            <div key={k} className="ac-item" onMouseDown={() => { onChange(i.nome || i); setQ(i.nome || i); setOpen(false); }}>
              {render ? render(i) : <span className="t">{i.nome || i}</span>}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

const fmtBR = (n) => "R$ " + (n || 0).toLocaleString("pt-BR", { minimumFractionDigits: 2, maximumFractionDigits: 2 });

// ---------------- NOVO ITEM DE ESTOQUE ----------------
function NovoItemForm({ app, onClose, edit }) {
  const [f, setF] = useState(edit
    ? { nome: edit.nome, un: edit.un, preco: edit.preco, saldo: edit.saldo, min: edit.min, forn: edit.forn, lead: edit.lead }
    : { nome: "", un: "un", preco: "", saldo: "", min: "", forn: "", lead: "" });
  const [img, setImg] = useState(edit && edit.imgUrl ? { url: edit.imgUrl, path: edit.imgPath } : null);
  const set = (k) => (e) => setF({ ...f, [k]: e.target.value });
  const sku = edit ? edit.sku : (f.nome.replace(/[^a-zA-Z]/g, "").slice(0, 4).toUpperCase() || "····").padEnd(4, "·");
  const submit = () => {
    if (!f.nome) return app.toast("Informe o nome do item", "crit");
    if (edit) { app.updateItem(edit.sku, { nome: f.nome, un: f.un, preco: +f.preco || 0, min: +f.min || 0, forn: f.forn, lead: +f.lead || 0, imgUrl: img ? img.url : null, imgPath: img ? img.path : null }); onClose(); app.toast("Alterações salvas", "ok"); return; }
    app.addItem({ sku: f.nome.replace(/[^a-zA-Z]/g, "").slice(0, 4).toUpperCase() || "ITEM", nome: f.nome, un: f.un,
      preco: +f.preco || 0, saldo: +f.saldo || 0, min: +f.min || 0, reservado: 0, forn: f.forn || "—", lead: +f.lead || 0,
      imgUrl: img ? img.url : null, imgPath: img ? img.path : null });
    onClose(); app.toast("Item adicionado ao estoque", "ok");
  };
  return (
    <Modal size="md" icon="box" title={edit ? "Editar item" : "Novo item de estoque"} sub={edit ? edit.sku : "Matéria-prima ou consumível"} onClose={onClose}
      footer={<><span className="hintnote"><Icon name="qr" size={14} />SKU: <b className="sku" style={{ color: "var(--accent)" }}>{sku}</b></span><span className="spacer" /><Btn onClick={onClose}>Cancelar</Btn><Btn variant="primary" icon="check" onClick={submit}>{edit ? "Salvar alterações" : "Salvar item"}</Btn></>}>
      <Field label="Nome do item" req><input className="fld" autoFocus value={f.nome} onChange={set("nome")} placeholder="Ex.: Chapa aço carbono 2,0mm" /></Field>
      <div className="field-grid c3">
        <Field label="Unidade" req>
          <select className="fld" value={f.un} onChange={set("un")}>
            {["un","kg","m","L","br","pç","cx"].map((u) => <option key={u} value={u}>{u}</option>)}
          </select>
        </Field>
        <Field label="Preço unitário"><div className="fld-wrap"><span className="pre">R$</span><input className="fld" type="number" value={f.preco} onChange={set("preco")} placeholder="0,00" /></div></Field>
        <Field label="Lead time" help="dias p/ compra"><input className="fld" type="number" value={f.lead} onChange={set("lead")} placeholder="0" /></Field>
      </div>
      <div className="field-grid c2">
        <Field label="Saldo inicial"><input className="fld" type="number" value={f.saldo} onChange={set("saldo")} placeholder="0" disabled={!!edit} /></Field>
        <Field label="Estoque mínimo" help="dispara alerta de compra"><input className="fld" type="number" value={f.min} onChange={set("min")} placeholder="0" /></Field>
      </div>
      <Field label="Fornecedor principal" opt><input className="fld" value={f.forn} onChange={set("forn")} placeholder="Ex.: Aços Sul" /></Field>
      <Field label="Imagem" opt><ImgUpload value={img} onChange={setImg} folder="estoque" height={140} toast={app.toast} /></Field>
    </Modal>
  );
}

// ---------------- NOVO / EDITAR PEDIDO ----------------
function NovoPedidoForm({ app, onClose, edit }) {
  const [cliente, setCliente] = useState(edit ? edit.cliente : "");
  const [prio, setPrio] = useState(edit ? edit.prio : 5);
  const [entrega, setEntrega] = useState(edit ? edit.entrega : "");
  // Cada linha: {tipo: 'produto'|'estoque', prod: nomeExibido, qtd, preco}
  const linhasIniciais = edit && Array.isArray(edit.itens) && edit.itens.length
    ? edit.itens.map((it) => ({ tipo: it.tipo || "produto", prod: it.nome || "", qtd: it.qtd || 1, preco: it.preco || 0 }))
    : edit
      ? [{ tipo: "produto", prod: edit.produto, qtd: edit.qtd, preco: Math.round(edit.valor / Math.max(edit.qtd, 1)) }]
      : [{ tipo: "produto", prod: "", qtd: 1, preco: 0 }];
  const [lines, setLines] = useState(linhasIniciais);
  const os = edit ? edit.os : String(Math.floor(100000 + Math.random() * 899999));
  const setLine = (i, k, v) => setLines(lines.map((l, j) => j === i ? { ...l, [k]: v } : l));
  const addLine = () => setLines([...lines, { tipo: "produto", prod: "", qtd: 1, preco: 0 }]);
  const rmLine = (i) => setLines(lines.filter((_, j) => j !== i));
  const total = lines.reduce((s, l) => s + (+l.qtd || 0) * (+l.preco || 0), 0);
  // ao trocar de tipo, limpa o produto selecionado
  const setTipo = (i, t) => setLines(lines.map((l, j) => j === i ? { ...l, tipo: t, prod: "", preco: 0 } : l));
  // ao selecionar o item, prefill o preço
  const onSelectItem = (i, nome) => {
    setLines(lines.map((l, j) => {
      if (j !== i) return l;
      if (l.tipo === "produto") {
        const p = app.produtos.find((x) => x.nome === nome);
        return { ...l, prod: nome, preco: p ? p.preco : l.preco };
      } else {
        const e = app.estoque.find((x) => x.nome === nome);
        return { ...l, prod: nome, preco: e ? e.preco : l.preco };
      }
    }));
  };

  // verificação de prazo usando schedule real (empresa + cada terceirizado)
  const entregaISO = /^\d{4}-/.test(entrega) ? entrega : null;
  const prazo = (() => {
    if (!entregaISO) return null;
    const empresaSch = (app.ws && app.ws.schedule) || null;
    const dispLocal = app.horasDisponiveis(entregaISO, empresaSch);
    if (dispLocal == null) return null;
    if (dispLocal < 0) return { erro: "data no passado" };
    let horasLocal = 0;
    let semEtapas = 0;
    const horasPorTerc = {}; // { tercIdOuVazio: { horas, nome, definido } }
    lines.forEach((l) => {
      if (l.tipo !== "produto") return; // venda direta de estoque não consome horas de produção
      const p = app.produtos.find((x) => x.nome === l.prod);
      if (!p) return;
      const h = app.calcProdutoHoras(p);
      const q = +l.qtd || 0;
      if (h.total === 0) semEtapas++;
      horasLocal += h.local * q;
      Object.entries(h.porTerceirizado || {}).forEach(([tid, horasUnit]) => {
        const t = tid !== "_default" ? app.terceirizados.find((x) => x._id === tid) : null;
        const chave = t ? t._id : "_default";
        const nome = t ? t.nome : "Terceirizado não definido";
        if (!horasPorTerc[chave]) horasPorTerc[chave] = { horas: 0, nome, definido: !!t, sch: t && t.schedule ? t.schedule : null };
        horasPorTerc[chave].horas += horasUnit * q;
      });
    });
    if (horasLocal === 0 && Object.keys(horasPorTerc).length === 0) {
      return { neutro: true, msg: semEtapas > 0 ? "Algum produto não tem etapas cadastradas — não dá pra avaliar o prazo." : null };
    }
    const empresaOk = horasLocal <= dispLocal;
    const terceirizados = Object.values(horasPorTerc).map((t) => {
      const disp = t.definido ? app.horasDisponiveis(entregaISO, t.sch) : null;
      return { ...t, disp, ok: disp == null ? true : t.horas <= disp };
    });
    const ok = empresaOk && terceirizados.every((t) => t.ok);
    return { ok, empresaOk, horasLocal, dispLocal, terceirizados };
  })();

  const submit = () => {
    if (!cliente) return app.toast("Selecione um cliente", "crit");
    const itens = lines.filter((l) => l.prod).map((l) => {
      const tipo = l.tipo === "estoque" ? "estoque" : "produto";
      const ref = tipo === "produto"
        ? app.produtos.find((x) => x.nome === l.prod)
        : app.estoque.find((x) => x.nome === l.prod);
      return {
        tipo,
        nome: l.prod,
        sku: ref ? ref.sku : "",
        qtd: +l.qtd || 1,
        preco: +l.preco || 0,
      };
    });
    if (itens.length === 0) return app.toast("Adicione pelo menos um item", "crit");
    const principal = itens[0];
    const payload = { cliente, itens, produto: principal.nome, qtd: principal.qtd, valor: total, prio, entrega: entrega || "—" };
    if (edit) { app.atualizarPedido(edit._id, payload); onClose(); app.toast(`Pedido OS ${os} atualizado`, "ok"); return; }
    app.criarPedido({ os, ...payload });
    onClose();
  };
  return (
    <Modal size="lg" icon="fileText" title={edit ? "Editar pedido" : "Novo pedido de venda"} sub={"Ordem de serviço " + os} onClose={onClose}
      footer={<><span className="hintnote"><Icon name="zap" size={14} /> Prioridade {prio}</span><span className="spacer" /><Btn onClick={onClose}>Cancelar</Btn><Btn variant="primary" icon="check" onClick={submit}>{edit ? "Salvar alterações" : "Criar pedido"}</Btn></>}>
      <div className="field-grid c2" style={{ marginBottom: 18 }}>
        <Field label="Cliente" req help="comece a digitar para buscar">
          <Autocomplete items={app.clientes} value={cliente} onChange={setCliente} placeholder="Buscar cliente…"
            render={(c) => <><span className="t">{c.nome}</span><span className="s">{c.cidade}/{c.uf}</span></>} />
        </Field>
        <Field label="Data de entrega"><div className="fld-wrap"><Icon name="calendar" size={15} className="ico-in" /><input className="fld" type="date" value={/^\d{4}-/.test(entrega) ? entrega : ""} onChange={(e) => setEntrega(e.target.value)} /></div></Field>
      </div>

      <div className="form-sec">Itens do pedido</div>
      <div className="lines">
        <div className="lrow lhead" style={{ gridTemplateColumns: "110px 1fr 80px 110px 110px 34px" }}><div>Tipo</div><div>Item</div><div className="right">Qtd</div><div className="right">Preço un.</div><div className="right">Subtotal</div><div></div></div>
        {lines.map((l, i) => {
          const opcoes = l.tipo === "estoque" ? app.estoque : app.produtos;
          return (
            <div key={i} className="lrow" style={{ gridTemplateColumns: "110px 1fr 80px 110px 110px 34px" }}>
              <div>
                <select className="fld" value={l.tipo || "produto"} onChange={(e) => setTipo(i, e.target.value)}>
                  <option value="produto">Produto</option>
                  <option value="estoque">Estoque</option>
                </select>
              </div>
              <div>
                <select className="fld" value={l.prod} onChange={(e) => onSelectItem(i, e.target.value)}>
                  <option value="">{l.tipo === "estoque" ? "Selecione o item do estoque…" : "Selecione o produto…"}</option>
                  {opcoes.map((x) => <option key={x.sku || x._id} value={x.nome}>{x.nome}</option>)}
                </select>
              </div>
              <div><input className="fld right" type="number" value={l.qtd} onChange={(e) => setLine(i, "qtd", e.target.value)} /></div>
              <div><input className="fld right" type="number" value={l.preco} onChange={(e) => setLine(i, "preco", e.target.value)} /></div>
              <div className="right mono" style={{ alignSelf: "center", fontWeight: 600, fontSize: 13 }}>{fmtBR((+l.qtd || 0) * (+l.preco || 0))}</div>
              <div>{lines.length > 1 && <IconBtn icon="trash" onClick={() => rmLine(i)} />}</div>
            </div>
          );
        })}
        <div className="lrow ltot" style={{ gridTemplateColumns: "110px 1fr 80px 110px 110px 34px" }}>
          <div><Btn size="sm" icon="plus" onClick={addLine}>Adicionar</Btn></div>
          <div></div><div></div>
          <div className="right muted small" style={{ alignSelf: "center" }}>Total</div>
          <div className="right mono" style={{ alignSelf: "center", fontSize: 15 }}>{fmtBR(total)}</div>
          <div></div>
        </div>
      </div>

      {prazo && prazo.erro && (
        <div className="help" style={{ marginTop: 14, color: "var(--crit)" }}><Icon name="alert" size={12} /> Data de entrega no passado.</div>
      )}
      {prazo && prazo.neutro && prazo.msg && (
        <div className="help" style={{ marginTop: 14 }}><Icon name="alert" size={12} /> {prazo.msg}</div>
      )}
      {prazo && !prazo.neutro && !prazo.erro && (
        <div className="note-inline" style={{
          display: "flex", gap: 10, padding: "10px 14px", borderRadius: "var(--radius)", marginTop: 14,
          background: prazo.ok ? "var(--ok-tint)" : "var(--crit-tint)",
          color: prazo.ok ? "var(--ok)" : "var(--crit)",
          fontSize: 13,
        }}>
          <Icon name={prazo.ok ? "checkCircle" : "alert"} size={16} />
          <div className="grow">
            <div><b>{prazo.ok ? "Prazo OK." : "Prazo apertado."}</b></div>
            {prazo.horasLocal > 0 && (
              <div className="small" style={{ marginTop: 4, color: "inherit", opacity: prazo.empresaOk ? 0.85 : 1 }}>
                {prazo.empresaOk ? "✓" : "✗"} Empresa: precisa <b>{prazo.horasLocal}h</b> · disponível <b>{prazo.dispLocal}h</b>
              </div>
            )}
            {prazo.terceirizados.map((t, i) => (
              <div key={i} className="small" style={{ marginTop: 2, color: "inherit", opacity: t.ok ? 0.85 : 1 }}>
                {t.ok ? "✓" : "✗"} {t.nome}: precisa <b>{t.horas}h</b>
                {t.disp != null ? <> · disponível <b>{t.disp}h</b></> : <> · <i>sem horário cadastrado</i></>}
              </div>
            ))}
          </div>
        </div>
      )}

      <div className="field-grid c2" style={{ marginTop: 18 }}>
        <Field label="Prioridade" help="0 = baixa · 9 = urgente"><PrioScale value={prio} onChange={setPrio} /></Field>
        <Field label="Observações" opt><input className="fld" placeholder="Ex.: entregar na obra" /></Field>
      </div>
    </Modal>
  );
}

// ---------------- NOVA OP ----------------
// Lista linhas abertas (tipo=produto) de todos os pedidos abertos/andamento,
// com a qtd já alocada em OPs ativas subtraída.
function linhasAbertas(app, produtoNome) {
  const out = [];
  const opsAtivas = (app.ops || []).filter((o) => o.status !== "finalizado" && o.status !== "cancelado");
  (app.pedidos || []).filter((p) => p.status === "aberto" || p.status === "andamento").forEach((p) => {
    const itens = app.normItens ? app.normItens(p) : (p.itens || []);
    itens.forEach((it, idx) => {
      if (it.tipo !== "produto") return;
      if (produtoNome && it.nome !== produtoNome) return;
      const alocado = opsAtivas.reduce((s, op) => {
        const ali = (op.itens || []).find((x) => x.pedidoId === p._id && x.lineIdx === idx);
        return s + (ali ? +ali.qtd || 0 : 0);
      }, 0);
      const disponivel = Math.max(0, (+it.qtd || 0) - alocado);
      if (disponivel > 0) {
        out.push({ pedidoId: p._id, lineIdx: idx, os: p.os, cliente: p.cliente, produto: it.nome, qtdTotal: +it.qtd || 0, alocado, disponivel });
      }
    });
  });
  return out;
}

function NovaOPForm({ app, onClose, fromPedido }) {
  // Modo inicial: se fromPedido tem os/_pedidoId, começa em "pedidos"; se nada, "avulsa"
  const inicioPedidos = !!(fromPedido && (fromPedido._pedidoId || fromPedido.os));
  const [modo, setModo] = useState(inicioPedidos ? "pedidos" : "avulsa");
  const [produto, setProduto] = useState(fromPedido ? (fromPedido.produto || "") : "");
  const [qtdAvulsa, setQtdAvulsa] = useState(fromPedido && fromPedido.qtd ? fromPedido.qtd : 1);
  const [prio, setPrio] = useState(fromPedido && fromPedido.prio != null ? fromPedido.prio : 5);

  // sel: { [`${pedidoId}-${lineIdx}`]: qtd selecionada (até disponivel) }
  const [sel, setSel] = useState(() => {
    const out = {};
    if (fromPedido && fromPedido._pedidoId) {
      const key = `${fromPedido._pedidoId}-${fromPedido._lineIdx || 0}`;
      out[key] = +fromPedido.qtd || 1;
    }
    return out;
  });

  // produtos com linhas abertas disponíveis (pra escolher como filtro)
  const produtosDisponiveis = useMemo(() => {
    const set = new Set();
    linhasAbertas(app).forEach((l) => set.add(l.produto));
    return [...set];
  }, [app.pedidos, app.ops]);

  // linhas exibidas quando modo = pedidos
  const linhas = useMemo(() => modo === "pedidos" ? linhasAbertas(app, produto) : [], [app.pedidos, app.ops, produto, modo]);

  // se a primeira linha selecionada determina o produto, ajusta o produto auto
  const produtoEfetivo = (() => {
    if (modo === "avulsa") return produto;
    if (produto) return produto;
    const primKey = Object.keys(sel).find((k) => sel[k] > 0);
    if (!primKey) return "";
    const [pid, lix] = primKey.split("-");
    const ped = app.pedidos.find((x) => x._id === pid);
    if (!ped) return "";
    const itens = app.normItens ? app.normItens(ped) : (ped.itens || []);
    return itens[+lix] && itens[+lix].nome || "";
  })();

  // etapas vêm do produto efetivo
  const produtoSel = app.produtos.find((p) => p.nome === produtoEfetivo);
  const etapasProduto = produtoSel && Array.isArray(produtoSel.etapas) ? produtoSel.etapas : [];
  const [etapasOn, setEtapasOn] = useState(() => etapasProduto.reduce((acc, e) => { acc[e.nome] = true; return acc; }, {}));
  useEffect(() => {
    setEtapasOn(etapasProduto.reduce((acc, e) => { acc[e.nome] = true; return acc; }, {}));
  }, [produtoEfetivo]);

  const opNum = useMemo(() => "OP-" + String(Math.floor(10000 + Math.random() * 89999)), []);
  const toggleEtapa = (nome) => setEtapasOn({ ...etapasOn, [nome]: !etapasOn[nome] });
  const horasOn = etapasProduto.filter((e) => etapasOn[e.nome]).reduce((s, e) => s + (+e.horas || 0), 0);

  const totalSel = Object.values(sel).reduce((s, q) => s + (+q || 0), 0);
  const planej = modo === "avulsa" ? (+qtdAvulsa || 0) : totalSel;

  const toggleLinha = (l, on) => {
    const key = `${l.pedidoId}-${l.lineIdx}`;
    setSel((prev) => {
      const n = { ...prev };
      if (on) n[key] = l.disponivel;
      else delete n[key];
      return n;
    });
  };
  const setLinhaQtd = (l, v) => {
    const key = `${l.pedidoId}-${l.lineIdx}`;
    const q = Math.max(0, Math.min(l.disponivel, +v || 0));
    setSel((prev) => { const n = { ...prev }; if (q > 0) n[key] = q; else delete n[key]; return n; });
  };

  const submit = () => {
    if (modo === "avulsa") {
      if (!produto) return app.toast("Selecione um produto", "crit");
      if (planej < 1) return app.toast("Qtd deve ser ≥ 1", "crit");
      app.criarOP({ op: opNum, produto, planej, prio });
    } else {
      const itensSelecionados = linhas
        .filter((l) => sel[`${l.pedidoId}-${l.lineIdx}`] > 0)
        .map((l) => ({ pedidoId: l.pedidoId, lineIdx: l.lineIdx, os: l.os, cliente: l.cliente, qtd: sel[`${l.pedidoId}-${l.lineIdx}`] }));
      if (itensSelecionados.length === 0) return app.toast("Selecione pelo menos uma linha de pedido", "crit");
      if (!produtoEfetivo) return app.toast("Não foi possível identificar o produto", "crit");
      // OS principal pra retrocompat: vazia se múltiplos
      const pedidoCampo = itensSelecionados.length === 1 ? itensSelecionados[0].os : "";
      app.criarOP({ op: opNum, produto: produtoEfetivo, pedido: pedidoCampo, planej, prio, itens: itensSelecionados });
    }
    onClose();
  };

  return (
    <Modal size="lg" icon="factory" title="Nova ordem de produção" sub={opNum} onClose={onClose}
      footer={<>
        <span className="hintnote"><Icon name="layers" size={14} /> {etapasProduto.filter((e) => etapasOn[e.nome]).length} etapas · {horasOn}h · planej {planej}</span>
        <span className="spacer" />
        <Btn onClick={onClose}>Cancelar</Btn>
        <Btn variant="primary" icon="check" onClick={submit}>Criar OP</Btn>
      </>}>
      <div className="field-grid c2">
        <Field label="Origem">
          <Choice value={modo} onChange={setModo} options={[{ v: "avulsa", l: "Avulsa" }, { v: "pedidos", l: "De pedidos" }]} />
        </Field>
        <Field label="Prioridade" help="0 = baixa · 9 = urgente"><PrioScale value={prio} onChange={setPrio} /></Field>
      </div>

      {modo === "avulsa" ? (
        <div className="field-grid c2" style={{ marginTop: 14 }}>
          <Field label="Produto" req>
            <select className="fld" value={produto} onChange={(e) => setProduto(e.target.value)}>
              <option value="">Selecione o produto…</option>
              {app.produtos.map((p) => <option key={p.sku} value={p.nome}>{p.nome}</option>)}
            </select>
          </Field>
          <Field label="Quantidade planejada" req><input className="fld" type="number" value={qtdAvulsa} onChange={(e) => setQtdAvulsa(e.target.value)} min="1" /></Field>
        </div>
      ) : (
        <>
          <div style={{ marginTop: 14 }}>
            <Field label="Filtrar por produto" help="apenas produtos com linhas abertas aparecem na lista">
              <select className="fld" value={produto} onChange={(e) => { setProduto(e.target.value); setSel({}); }}>
                <option value="">Todos os produtos com pedidos abertos</option>
                {produtosDisponiveis.map((nome) => <option key={nome} value={nome}>{nome}</option>)}
              </select>
            </Field>
          </div>
          <div className="form-sec">Linhas de pedido disponíveis</div>
          {linhas.length === 0 ? (
            <div className="help"><Icon name="alert" size={12} /> {produto ? `Nenhuma linha aberta de ${produto}.` : "Sem linhas abertas de produtos cadastrados. Crie um pedido com uma linha tipo Produto primeiro."}</div>
          ) : (
            <div className="lines">
              <div className="lrow lhead" style={{ gridTemplateColumns: "36px 90px 1.4fr 1fr 100px 90px" }}>
                <div></div><div>OS</div><div>Cliente</div><div>Produto</div><div className="right">Disp.</div><div className="right">Selecionar</div>
              </div>
              {linhas.map((l) => {
                const key = `${l.pedidoId}-${l.lineIdx}`;
                const q = sel[key] || 0;
                const checked = q > 0;
                return (
                  <div key={key} className="lrow" style={{ gridTemplateColumns: "36px 90px 1.4fr 1fr 100px 90px", padding: "8px 0" }}>
                    <div style={{ display: "grid", placeItems: "center" }}>
                      <input type="checkbox" checked={checked} onChange={(e) => toggleLinha(l, e.target.checked)} />
                    </div>
                    <div style={{ padding: "0 12px", alignSelf: "center" }}><span className="mono small strong">{l.os}</span></div>
                    <div style={{ padding: "0 12px", alignSelf: "center", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{l.cliente}</div>
                    <div style={{ padding: "0 12px", alignSelf: "center", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{l.produto}</div>
                    <div className="right mono" style={{ padding: "0 12px", alignSelf: "center" }}>{l.disponivel}{l.alocado > 0 ? <span className="muted small"> /{l.qtdTotal}</span> : ""}</div>
                    <div style={{ padding: "0 12px", alignSelf: "center" }}>
                      <input className="fld right" type="number" min="0" max={l.disponivel} value={q} onChange={(e) => setLinhaQtd(l, e.target.value)} disabled={!checked} />
                    </div>
                  </div>
                );
              })}
              <div className="lrow ltot" style={{ gridTemplateColumns: "36px 90px 1.4fr 1fr 100px 90px" }}>
                <div></div><div></div><div></div>
                <div className="right muted small" style={{ alignSelf: "center" }}>Total selecionado</div>
                <div></div>
                <div className="right mono strong" style={{ alignSelf: "center", fontSize: 15, padding: "0 12px" }}>{totalSel}</div>
              </div>
            </div>
          )}
        </>
      )}

      <div className="form-sec">Roteiro de produção</div>
      {!produtoEfetivo ? (
        <div className="help">Selecione um produto{modo === "pedidos" ? " ou marque uma linha de pedido" : ""} para ver suas etapas.</div>
      ) : etapasProduto.length === 0 ? (
        <div className="help"><Icon name="alert" size={12} /> O produto <b>{produtoEfetivo}</b> não tem etapas cadastradas. Edite o produto para definir o roteiro.</div>
      ) : (
        <div className="checklist">
          {etapasProduto.map((e, i) => (
            <div key={e.nome + i} className={"check-item" + (etapasOn[e.nome] ? " done" : "")} onClick={() => toggleEtapa(e.nome)}>
              <span className="order">{i + 1}</span>
              <span className="nm">{e.nome}</span>
              <span className="meta">{e.horas}h · {e.modo === "terceirizado" ? "terceirizado" : "local"}</span>
              <span className="box"><Icon name="check" size={13} /></span>
            </div>
          ))}
        </div>
      )}
      <div className="help" style={{ marginTop: 8 }}>Ao finalizar a OP, dá baixa nos insumos da BOM no estoque ({planej > 0 ? planej + "×" : ""} BOM do produto).</div>
    </Modal>
  );
}

// ---------------- LANÇAMENTO FINANCEIRO ----------------
function LancamentoForm({ app, onClose, edit }) {
  const [tipo, setTipo] = useState(edit ? edit.tipo : "entrada");
  const [status, setStatus] = useState(edit ? edit.status : "pago");
  const [desc, setDesc] = useState(edit ? edit.desc : "");
  const [cat, setCat] = useState(edit ? edit.cat : "Vendas");
  const [canal, setCanal] = useState(edit ? (edit.canal || "loja") : "loja");
  const [valor, setValor] = useState(edit ? edit.valor : "");
  const [venc, setVenc] = useState("");
  const submit = () => {
    if (!desc) return app.toast("Informe a descrição", "crit");
    const data = edit ? edit.data : new Date().toLocaleDateString("pt-BR", { day: "2-digit", month: "short" }).replace(".", "");
    const payload = { data, desc, cat, tipo, origem: "manual", canal, valor: +valor || 0, status, venc: status === "pendente" ? (venc || data) : undefined };
    if (edit) app.lancamentosApi.update(edit._id, payload); else app.lancamentosApi.add(payload, true);
    onClose(); app.toast(edit ? "Lançamento atualizado" : "Lançamento registrado", "ok");
  };
  return (
    <Modal size="md" icon="wallet" title={edit ? "Editar lançamento" : "Novo lançamento"} sub="Movimentação manual de caixa" onClose={onClose}
      footer={<><span className="spacer" /><Btn onClick={onClose}>Cancelar</Btn><Btn variant="primary" icon="check" onClick={submit}>{edit ? "Salvar" : "Lançar"}</Btn></>}>
      <Field label="Tipo" req>
        <Choice value={tipo} onChange={setTipo} options={[{ v: "entrada", l: "Entrada" }, { v: "saida", l: "Saída" }]} />
      </Field>
      <Field label="Descrição" req><input className="fld" autoFocus value={desc} onChange={(e) => setDesc(e.target.value)} placeholder="Ex.: Conta de energia — junho" /></Field>
      <div className="field-grid c2">
        <Field label="Categoria">
          <select className="fld" value={cat} onChange={(e) => setCat(e.target.value)}>{["Vendas","Matéria-prima","Despesa fixa","Pessoal","Impostos","Outras"].map((c) => <option key={c}>{c}</option>)}</select>
        </Field>
        <Field label="Valor" req><div className="fld-wrap"><span className="pre">R$</span><input className="fld" type="number" value={valor} onChange={(e) => setValor(e.target.value)} placeholder="0,00" /></div></Field>
      </div>
      <Field label="Canal de origem">
        <select className="fld" value={canal} onChange={(e) => setCanal(e.target.value)}>
          <option value="loja">Loja / Balcão</option>
          <option value="mercado_livre">Mercado Livre</option>
          <option value="shopee">Shopee</option>
        </select>
      </Field>
      <div className="field-grid c2">
        <Field label="Vencimento"><div className="fld-wrap"><Icon name="calendar" size={15} className="ico-in" /><input className="fld" type="date" value={venc} onChange={(e) => setVenc(e.target.value)} /></div></Field>
        <Field label="Situação">
          <Choice value={status} onChange={setStatus} options={[{ v: "pago", l: "Pago" }, { v: "pendente", l: "Pendente" }]} />
        </Field>
      </div>
    </Modal>
  );
}

// ---------------- RECEBER COMPRA ----------------
function ReceberCompraForm({ app, onClose, compra }) {
  const c = compra || app.compras.find((x) => x.status === "solicitada") || app.compras[0];
  const [qtdReceb, setQtdReceb] = useState(c ? c.qtd : 0);
  const [nfNum, setNfNum] = useState("");
  if (!c) {
    return (
      <Modal size="sm" icon="truck" title="Receber compra" onClose={onClose}
        footer={<><span className="spacer" /><Btn onClick={onClose}>Fechar</Btn></>}>
        <div className="help">Nenhuma compra disponível para recebimento. Cadastre uma compra primeiro.</div>
      </Modal>
    );
  }
  const submit = () => { app.receberCompra(c._id, { qtdRecebida: qtdReceb, nfNum }); onClose(); };
  return (
    <Modal size="md" icon="truck" title="Receber compra" sub={c.item} onClose={onClose}
      footer={<><span className="hintnote"><Icon name="check" size={14} /> Gera entrada + financeiro</span><span className="spacer" /><Btn onClick={onClose}>Cancelar</Btn><Btn variant="primary" icon="check" onClick={submit}>Confirmar recebimento</Btn></>}>
      <div className="sumbox" style={{ marginBottom: 16 }}>
        <div className="srow"><span className="muted">Fornecedor</span><span className="v">{c.forn}</span></div>
        <div className="srow"><span className="muted">Item</span><span className="v"><span className="sku">{c.sku}</span> {c.item}</span></div>
        <div className="srow"><span className="muted">Qtd. solicitada</span><span className="v">{c.qtd} {c.un}</span></div>
        <div className="srow tot"><span>Valor da compra</span><span className="v">{fmtBR(c.valor)}</span></div>
      </div>
      <div className="field-grid c2">
        <Field label="Qtd. recebida" req help="confira com a nota fiscal"><input className="fld" type="number" value={qtdReceb} onChange={(e) => setQtdReceb(e.target.value)} /></Field>
        <Field label="Nº da nota fiscal"><input className="fld" placeholder="000000" value={nfNum} onChange={(e) => setNfNum(e.target.value)} /></Field>
      </div>
      <Field label="Anexar nota fiscal" opt><div className="upzone"><div className="uz-ico"><Icon name="paperclip" size={18} /></div><div className="uz-t">Anexar PDF ou foto da NF</div><div className="uz-s">fica vinculada à compra e ao estoque</div></div></Field>
      {+qtdReceb !== c.qtd && <div className="help" style={{ color: "var(--warn)" }}><Icon name="alert" size={12} /> Quantidade diverge da solicitação ({c.qtd} {c.un}) — o saldo será ajustado pelo recebido.</div>}
    </Modal>
  );
}

// ---------------- NOVO CLIENTE ----------------
function NovoClienteForm({ app, onClose, edit }) {
  const [f, setF] = useState(edit ? { ...edit } : { nome: "", doc: "", tel: "", email: "", cidade: "", uf: "RS" });
  const set = (k) => (e) => setF({ ...f, [k]: e.target.value });
  const submit = () => {
    if (!f.nome) return app.toast("Informe o nome do cliente", "crit");
    const payload = { nome: f.nome, doc: f.doc, tel: f.tel, email: f.email, cidade: f.cidade, uf: f.uf,
      pedidos: edit ? edit.pedidos : 0, total: edit ? edit.total : 0, ultimo: edit ? edit.ultimo : "—" };
    if (edit) app.clientesApi.update(edit._id, payload); else app.clientesApi.add(payload);
    onClose(); app.toast(edit ? "Cliente atualizado" : "Cliente cadastrado", "ok");
  };
  return (
    <Modal size="md" icon="users" title={edit ? "Editar cliente" : "Novo cliente"} onClose={onClose}
      footer={<><span className="spacer" /><Btn onClick={onClose}>Cancelar</Btn><Btn variant="primary" icon="check" onClick={submit}>{edit ? "Salvar alterações" : "Salvar cliente"}</Btn></>}>
      <div className="field-grid c2" style={{ marginBottom: 14 }}>
        <Field label="Nome / Razão social" req><input className="fld" autoFocus value={f.nome} onChange={set("nome")} placeholder="Nome do cliente" /></Field>
        <Field label="CPF / CNPJ" req><input className="fld" value={f.doc} onChange={set("doc")} placeholder="00.000.000/0000-00" /></Field>
      </div>
      <div className="field-grid c2" style={{ marginBottom: 14 }}>
        <Field label="Telefone"><div className="fld-wrap"><input className="fld" value={f.tel} onChange={set("tel")} placeholder="(00) 00000-0000" /></div></Field>
        <Field label="E-mail"><input className="fld" type="email" value={f.email} onChange={set("email")} placeholder="email@empresa.com" /></Field>
      </div>
      <div className="field-grid c3" style={{ marginBottom: 14 }}>
        <Field label="Cidade"><input className="fld" value={f.cidade} onChange={set("cidade")} /></Field>
        <Field label="UF"><input className="fld" maxLength="2" value={f.uf} onChange={set("uf")} placeholder="RS" /></Field>
        <Field label="Endereço" opt><input className="fld" /></Field>
      </div>
      <Field label="Observações" opt><textarea className="fld" placeholder="Anotações sobre o cliente…"></textarea></Field>
    </Modal>
  );
}

// ---------------- NOVO PRODUTO ----------------
function NovoProdutoForm({ app, onClose, edit }) {
  const [nome, setNome] = useState(edit ? edit.nome : "");
  const [preco, setPreco] = useState(edit ? edit.preco : "");
  const [lote, setLote] = useState(edit ? (edit.lote || 1) : 1);
  const [modo, setModo] = useState(edit ? edit.modo : "Sob demanda");
  const [bom, setBom] = useState(edit && edit.bom && edit.bom.length
    ? edit.bom.map((b) => ({ ins: (app.estoque.find((x) => x.sku === b.sku) || {}).nome || "", qtd: b.qtd }))
    : [{ ins: "", qtd: 1 }]);
  const [etapas, setEtapas] = useState(edit && Array.isArray(edit.etapas) && edit.etapas.length
    ? edit.etapas.map((e) => ({ nome: e.nome || "", horas: e.horas || 0, modo: e.modo === "terceirizado" ? "terceirizado" : "local", terceirizadoId: e.terceirizadoId || "" }))
    : [{ nome: "", horas: 0, modo: "local", terceirizadoId: "" }]);
  const [img, setImg] = useState(edit && edit.imgUrl ? { url: edit.imgUrl, path: edit.imgPath } : null);
  const setB = (i, k, v) => setBom(bom.map((l, j) => j === i ? { ...l, [k]: v } : l));
  const setE = (i, k, v) => setEtapas(etapas.map((l, j) => j === i ? { ...l, [k]: v } : l));
  const custo = bom.reduce((s, l) => { const e = app.estoque.find((x) => x.nome === l.ins); return s + (e ? e.preco * (+l.qtd || 0) : 0); }, 0);
  const horasTotal = etapas.reduce((s, e) => s + (+e.horas || 0), 0);
  const horasLocal = etapas.filter((e) => e.modo === "local").reduce((s, e) => s + (+e.horas || 0), 0);
  const horasTerc = etapas.filter((e) => e.modo === "terceirizado").reduce((s, e) => s + (+e.horas || 0), 0);
  const tempoLabel = horasTotal > 0 ? (horasTotal % 1 === 0 ? horasTotal + "h" : horasTotal.toFixed(1) + "h") : "—";
  const submit = () => {
    if (!nome) return app.toast("Informe o nome do produto", "crit");
    const bomOut = bom.filter((l) => l.ins).map((l) => ({ sku: (app.estoque.find((x) => x.nome === l.ins) || {}).sku || "", qtd: +l.qtd || 0 }));
    const etapasOut = etapas.filter((e) => e.nome).map((e) => {
      const out = { nome: e.nome, horas: +e.horas || 0, modo: e.modo === "terceirizado" ? "terceirizado" : "local" };
      if (out.modo === "terceirizado" && e.terceirizadoId) out.terceirizadoId = e.terceirizadoId;
      return out;
    });
    const sku = edit ? edit.sku : ((nome.replace(/[^a-zA-Z]/g, "").slice(0, 3).toUpperCase() || "PRD") + "-" + String(Math.floor(10 + Math.random() * 89)));
    const payload = { sku, nome, preco: +preco || 0, tempo: tempoLabel, lote: +lote || 1, modo, bom: bomOut, etapas: etapasOut, custo: Math.round(custo), imgUrl: img ? img.url : null, imgPath: img ? img.path : null };
    if (edit) app.produtosApi.update(edit._id, payload); else app.produtosApi.add(payload);
    onClose(); app.toast(edit ? "Produto atualizado" : "Produto cadastrado", "ok");
  };
  return (
    <Modal size="lg" icon="package" title={edit ? "Editar produto" : "Novo produto"} sub="Produto acabado com lista de materiais (BOM)" onClose={onClose}
      footer={<><span className="hintnote"><Icon name="dollar" size={14} /> Custo estimado: <b style={{ color: "var(--ink)" }}>{fmtBR(custo)}</b></span><span className="spacer" /><Btn onClick={onClose}>Cancelar</Btn><Btn variant="primary" icon="check" onClick={submit}>Salvar produto</Btn></>}>
      <div className="field-grid c2" style={{ marginBottom: 14 }}>
        <Field label="Nome do produto" req><input className="fld" autoFocus value={nome} onChange={(e) => setNome(e.target.value)} placeholder="Ex.: Portão basculante 3,0 x 2,5m" /></Field>
        <Field label="Preço de venda" req><div className="fld-wrap"><span className="pre">R$</span><input className="fld" type="number" value={preco} onChange={(e) => setPreco(e.target.value)} placeholder="0,00" /></div></Field>
      </div>
      <Field label="Imagem" opt><ImgUpload value={img} onChange={setImg} folder="produtos" height={160} toast={app.toast} /></Field>
      <div className="field-grid c3" style={{ marginBottom: 4 }}>
        <Field label="Tempo de produção" help="soma das etapas (calculado automático)">
          <div className="fld" style={{ display: "flex", alignItems: "center", color: horasTotal > 0 ? "var(--ink)" : "var(--muted)", fontWeight: 600 }}>
            {tempoLabel}{horasTerc > 0 && <span className="muted small" style={{ marginLeft: 8, fontWeight: 400 }}>({horasLocal}h local + {horasTerc}h terc.)</span>}
          </div>
        </Field>
        <Field label="Lote padrão"><input className="fld" type="number" value={lote} onChange={(e) => setLote(e.target.value)} placeholder="1" /></Field>
        <Field label="Modo"><select className="fld" value={modo} onChange={(e) => setModo(e.target.value)}>{["Sob demanda","Para estoque","Misto"].map((m) => <option key={m}>{m}</option>)}</select></Field>
      </div>

      <div className="form-sec">Lista de materiais (BOM)</div>
      <div className="lines">
        <div className="lrow lhead" style={{ gridTemplateColumns: "1fr 90px 120px 34px" }}><div>Insumo</div><div className="right">Qtd</div><div className="right">Custo</div><div></div></div>
        {bom.map((l, i) => {
          const e = app.estoque.find((x) => x.nome === l.ins);
          return (
            <div key={i} className="lrow" style={{ gridTemplateColumns: "1fr 90px 120px 34px" }}>
              <div><select className="fld" value={l.ins} onChange={(ev) => setB(i, "ins", ev.target.value)}><option value="">Selecione o insumo…</option>{app.estoque.map((x) => <option key={x.sku} value={x.nome}>{x.nome}</option>)}</select></div>
              <div><input className="fld right" type="number" value={l.qtd} onChange={(ev) => setB(i, "qtd", ev.target.value)} /></div>
              <div className="right mono" style={{ alignSelf: "center", fontWeight: 600, fontSize: 13 }}>{fmtBR(e ? e.preco * (+l.qtd || 0) : 0)}</div>
              <div>{bom.length > 1 && <IconBtn icon="trash" onClick={() => setBom(bom.filter((_, j) => j !== i))} />}</div>
            </div>
          );
        })}
        <div className="lrow ltot" style={{ gridTemplateColumns: "1fr 90px 120px 34px" }}><div><Btn size="sm" icon="plus" onClick={() => setBom([...bom, { ins: "", qtd: 1 }])}>Adicionar insumo</Btn></div><div className="right muted small" style={{ alignSelf: "center" }}>Custo</div><div className="right mono" style={{ alignSelf: "center", fontSize: 15 }}>{fmtBR(custo)}</div><div></div></div>
      </div>

      <div className="form-sec">Etapas de produção</div>
      {app.etapasCatalogo.length === 0 && (
        <div className="help" style={{ marginBottom: 10 }}>
          <Icon name="alert" size={12} /> Nenhuma etapa cadastrada ainda. Vá em <a style={{ color: "var(--accent)", cursor: "pointer" }} onClick={() => { onClose(); app.setRoute("configuracoes"); }}>Configurações → Etapas de produção</a> para criar (Impressão 3D, Corte Laser, Usinagem, etc.).
        </div>
      )}
      <div className="lines">
        <div className="lrow lhead" style={{ gridTemplateColumns: "1fr 80px 140px 1fr 34px" }}><div>Etapa</div><div className="right">Horas</div><div>Execução</div><div>Terceirizado</div><div></div></div>
        {etapas.map((l, i) => (
          <div key={i} className="lrow" style={{ gridTemplateColumns: "1fr 80px 140px 1fr 34px" }}>
            <div>
              <select className="fld" value={l.nome} onChange={(ev) => setE(i, "nome", ev.target.value)}>
                <option value="">Selecione a etapa…</option>
                {app.etapasCatalogo.map((et) => <option key={et._id} value={et.nome}>{et.nome}</option>)}
              </select>
            </div>
            <div><input className="fld right" type="number" step="0.5" min="0" value={l.horas} onChange={(ev) => setE(i, "horas", ev.target.value)} /></div>
            <div>
              <select className="fld" value={l.modo} onChange={(ev) => setE(i, "modo", ev.target.value)}>
                <option value="local">Local</option>
                <option value="terceirizado">Terceirizado</option>
              </select>
            </div>
            <div>
              {l.modo === "terceirizado" ? (
                <select className="fld" value={l.terceirizadoId || ""} onChange={(ev) => setE(i, "terceirizadoId", ev.target.value)}>
                  <option value="">— sem definir —</option>
                  {app.terceirizados.map((t) => <option key={t._id} value={t._id}>{t.nome}</option>)}
                </select>
              ) : (
                <div className="fld" style={{ display: "flex", alignItems: "center", color: "var(--muted)", fontSize: 12 }}>—</div>
              )}
            </div>
            <div>{etapas.length > 1 && <IconBtn icon="trash" onClick={() => setEtapas(etapas.filter((_, j) => j !== i))} />}</div>
          </div>
        ))}
        <div className="lrow ltot" style={{ gridTemplateColumns: "1fr 80px 140px 1fr 34px" }}>
          <div><Btn size="sm" icon="plus" onClick={() => setEtapas([...etapas, { nome: "", horas: 0, modo: "local", terceirizadoId: "" }])} disabled={app.etapasCatalogo.length === 0}>Adicionar etapa</Btn></div>
          <div className="right muted small" style={{ alignSelf: "center" }}>Total</div>
          <div className="mono" style={{ alignSelf: "center", fontSize: 14, fontWeight: 600 }}>{horasTotal}h</div>
          <div></div>
          <div></div>
        </div>
      </div>
    </Modal>
  );
}

// ---------------- NOVA COMPRA ----------------
function NovaCompraForm({ app, onClose }) {
  const [ins, setIns] = useState("");
  const [forn, setForn] = useState("");
  const [qtd, setQtd] = useState("");
  const [valor, setValor] = useState("");
  const [motivo, setMotivo] = useState("");
  const e = app.estoque.find((x) => x.nome === ins);
  // ao escolher um insumo do estoque, prefill fornecedor e sugere a qtd de reposição
  const pick = (nome) => {
    setIns(nome);
    const it = app.estoque.find((x) => x.nome === nome);
    if (it) { setForn(it.forn || ""); if (!qtd) setQtd(Math.max(it.min - it.saldo, 0) || it.min); }
  };
  const un = e ? e.un : "un";
  const submit = () => {
    if (!ins) return app.toast("Selecione o insumo", "crit");
    const sku = e ? e.sku : (ins.replace(/[^a-zA-Z]/g, "").slice(0, 4).toUpperCase() || "ITEM");
    app.comprasApi.add({ sku, item: ins, qtd: +qtd || 0, un, forn: forn || (e && e.forn) || "—",
      valor: +valor || (e ? Math.round(e.preco * (+qtd || 0)) : 0), motivo: motivo || "Compra manual", status: "solicitada" }, true);
    onClose(); app.toast("Compra solicitada", "ok", { sub: ins });
  };
  const estValor = +valor || (e ? Math.round(e.preco * (+qtd || 0)) : 0);
  return (
    <Modal size="md" icon="cart" title="Nova compra" sub="Pedido de insumo a fornecedor" onClose={onClose}
      footer={<><span className="hintnote"><Icon name="dollar" size={14} /> Estimado: <b style={{ color: "var(--ink)" }}>{fmtBR(estValor)}</b></span><span className="spacer" /><Btn onClick={onClose}>Cancelar</Btn><Btn variant="primary" icon="check" onClick={submit}>Solicitar compra</Btn></>}>
      <Field label="Insumo" req help="escolha um item de estoque para preencher fornecedor automaticamente">
        <select className="fld" value={ins} onChange={(ev) => pick(ev.target.value)}>
          <option value="">Selecione o insumo…</option>
          {app.estoque.map((x) => <option key={x.sku} value={x.nome}>{x.nome}</option>)}
        </select>
      </Field>
      <div className="field-grid c2">
        <Field label="Fornecedor"><input className="fld" value={forn} onChange={(ev) => setForn(ev.target.value)} placeholder="Ex.: Aços Sul" /></Field>
        <Field label={"Quantidade (" + un + ")"} req><input className="fld" type="number" value={qtd} onChange={(ev) => setQtd(ev.target.value)} placeholder="0" /></Field>
      </div>
      <div className="field-grid c2">
        <Field label="Valor total" help="em branco = estimado pelo preço de tabela"><div className="fld-wrap"><span className="pre">R$</span><input className="fld" type="number" value={valor} onChange={(ev) => setValor(ev.target.value)} placeholder={e ? String(Math.round(e.preco * (+qtd || 0))) : "0,00"} /></div></Field>
        <Field label="Motivo" opt><input className="fld" value={motivo} onChange={(ev) => setMotivo(ev.target.value)} placeholder="Ex.: reposição de estoque" /></Field>
      </div>
    </Modal>
  );
}

const MODALS = {
  novoItem: NovoItemForm,
  novoPedido: NovoPedidoForm,
  novaOP: NovaOPForm,
  lancamento: LancamentoForm,
  receberCompra: ReceberCompraForm,
  novoCliente: NovoClienteForm,
  novoProduto: NovoProdutoForm,
  novaCompra: NovaCompraForm,
};

function ModalHost({ modal, app, onClose }) {
  if (!modal) return null;
  const Comp = MODALS[modal.type];
  if (!Comp) return null;
  return <Comp app={app} onClose={onClose} {...(modal.props || {})} />;
}

Object.assign(window, { Modal, Field, Choice, PrioScale, Autocomplete, ModalHost, MODALS });
