/* global React, Icon, Button, Badge, Card, Field, PageHead, brl, fmtDate,
          useProdutosList, useFornecedoresList, gerarNumPC, hojeIso */

// ─── Sugestão de Compra (módulo Estoque) ─────────────────────────────────────
// Avisa o que está acabando ANTES de faltar — hoje ela descobre quando a produção
// para por falta de tampa. Decisões travadas com a Naii:
//   1. dispara por COBERTURA (estoque ÷ consumo médio diário), não por mínimo fixo;
//   2. desconta o que JÁ está a caminho (senão ela compra em dobro);
//   3. prazo de entrega vem do fornecedor (default 15 dias);
//   4. repõe até a cobertura-alvo (60 dias, ajustável), no múltiplo de compra;
//   5. insumo e produto de venda em ABAS separadas (lógicas parecidas, listas distintas);
//   6. da seleção sai um PEDIDO DE COMPRA por fornecedor;
//   7. dado sujo (estoque negativo, insumo sem custo) aparece, não some.

const PRAZO_PADRAO_DIAS   = 15;   // fornecedor sem prazo informado
const FOLGA_DIAS          = 7;    // gordura sobre o prazo — comprar no limite é arriscado
const COBERTURA_PADRAO    = 60;   // dias de estoque que a compra tenta recompor
const COBERTURAS          = [30, 45, 60, 90];
const MOTIVO_CONSUMO_OP   = 'Envio p/ industrialização';   // consumo real de insumo
const MOTIVO_VENDA_B2B    = 'Venda';                        // baixa da venda (desde a correção)

const diasAtras = (n) => { const d = new Date(); d.setDate(d.getDate() - n); return d.toISOString().slice(0, 10); };
const arredondaPraCima = (v, mult) => { const m = Math.max(1, Number(mult) || 1); return Math.ceil(Math.max(0, v) / m) * m; };

// ── Carrega tudo o que a conta precisa ───────────────────────────────────────
// Uma função só, pra a tela não virar uma cascata de useEffect.
async function carregarBaseSugestao() {
  const sb = window.tmSupabase;
  if (!sb) return null;
  const d30 = diasAtras(30), d90 = diasAtras(90);

  const [movRes, itensVendaRes, pcRes, opRes] = await Promise.all([
    // consumo de INSUMO: saída real gravada pela Ordem de Produção
    sb.from('movimentacoes_estoque').select('produto_id, sku, quantidade, quando, motivo')
      .eq('motivo', MOTIVO_CONSUMO_OP).gte('quando', d90),
    // consumo de PRODUTO DE VENDA: itens de pedidos faturados (cobre B2B e marketplace).
    // Uso pedido_itens em vez de movimentacoes porque a baixa de venda só passou a
    // existir agora — o histórico de movimento não tem as vendas antigas.
    sb.from('pedido_itens').select('produto_id, sku, quantidade, pedido_id'),
    // o que já está comprado e ainda não chegou
    sb.from('pedido_compra_itens').select('insumo_id, quantidade, quantidade_recebida, pedido_compra_id'),
    // o que está em produção e vai virar acabado
    sb.from('ordem_producao_itens').select('produto_id, quantidade, quantidade_recebida, ordem_id'),
  ]);

  // pedidos faturados no período (pra filtrar os itens de venda)
  const pedRes = await sb.from('pedidos').select('id, status, data_venda, created_at')
    .eq('status', 'Atendido').gte('created_at', d90);
  const pedById = {};
  (pedRes.data || []).forEach(p => { pedById[p.id] = p; });

  // pedidos de compra ainda pendentes
  const pcHeadRes = await sb.from('pedidos_compra').select('id, status, fornecedor_id, data_emissao');
  const pcById = {};
  (pcHeadRes.data || []).forEach(p => { pcById[p.id] = p; });

  // OPs ainda em curso
  const opHeadRes = await sb.from('ordens_producao').select('id, status');
  const opById = {};
  (opHeadRes.data || []).forEach(o => { opById[o.id] = o; });

  return {
    movs: movRes.data || [], itensVenda: itensVendaRes.data || [], pedById,
    pcItens: pcRes.data || [], pcById,
    opItens: opRes.data || [], opById,
  };
}

// ── O cálculo ────────────────────────────────────────────────────────────────
// consumoDiario = max(taxa de 30d, taxa de 90d). A produção dela é em LOTE, então
// 30d sozinho é ruidoso (um mês sem OP diria "consumo zero") e 90d sozinho não
// enxerga aceleração — que é justamente o que ela quer pegar. O max erra pro lado
// de não faltar.
function calcularSugestoes(produtos, base, coberturaAlvo, prazoPorProduto) {
  if (!base) return [];
  const d30 = diasAtras(30);
  const hoje = new Date();

  // consumo por produto, nas duas janelas
  const cons = {};   // produtoId → { q30, q90 }
  const soma = (pid, qtd, dentro30) => {
    if (!pid) return;
    if (!cons[pid]) cons[pid] = { q30: 0, q90: 0 };
    cons[pid].q90 += qtd;
    if (dentro30) cons[pid].q30 += qtd;
  };
  base.movs.forEach(m => {
    const q = Math.abs(Number(m.quantidade) || 0);
    const quando = String(m.quando || '').slice(0, 10);
    soma(m.produto_id, q, quando >= d30);
  });
  base.itensVenda.forEach(it => {
    const ped = base.pedById[it.pedido_id];
    if (!ped) return;   // pedido fora da janela ou não faturado
    const quando = String(ped.data_venda || ped.created_at || '').slice(0, 10);
    soma(it.produto_id, Number(it.quantidade) || 0, quando >= d30);
  });

  // o que já vem a caminho
  const aCaminho = {};
  base.pcItens.forEach(it => {
    const pc = base.pcById[it.pedido_compra_id];
    if (!pc || (pc.status !== 'enviado' && pc.status !== 'recebido_parcial')) return;
    const falta = Math.max(0, (Number(it.quantidade) || 0) - (Number(it.quantidade_recebida) || 0));
    if (falta > 0) aCaminho[it.insumo_id] = (aCaminho[it.insumo_id] || 0) + falta;
  });
  base.opItens.forEach(it => {
    const op = base.opById[it.ordem_id];
    if (!op || (op.status !== 'enviada' && op.status !== 'em_producao')) return;
    const falta = Math.max(0, (Number(it.quantidade) || 0) - (Number(it.quantidade_recebida) || 0));
    if (falta > 0) aCaminho[it.produto_id] = (aCaminho[it.produto_id] || 0) + falta;
  });

  return (produtos || []).map(p => {
    const c = cons[p.id] || { q30: 0, q90: 0 };
    const consumoDiario = Math.max(c.q30 / 30, c.q90 / 90);
    const estoque = Number(p.estoque != null ? p.estoque : p.est) || 0;
    const vindo = aCaminho[p.id] || 0;
    const disponivel = estoque + vindo;
    const minimo = Number(p.estoque_minimo != null ? p.estoque_minimo : p.min) || 0;

    const prazo = prazoPorProduto[p.id] != null ? prazoPorProduto[p.id] : PRAZO_PADRAO_DIAS;
    const cobertura = consumoDiario > 0 ? disponivel / consumoDiario : null;   // null = sem consumo
    const gatilhoDias = prazo + FOLGA_DIAS;

    // Sem histórico de consumo o cálculo por cobertura não existe → cai no mínimo,
    // que continua valendo como piso (é o que o app já usava).
    const porCobertura = consumoDiario > 0 && cobertura != null && cobertura <= gatilhoDias;
    const porMinimo    = consumoDiario === 0 && minimo > 0 && disponivel <= minimo;
    const sugerir = porCobertura || porMinimo;

    const alvoBruto = consumoDiario > 0
      ? (consumoDiario * coberturaAlvo) - disponivel
      : (minimo * 2) - disponivel;
    const mult = Math.max(1, Number(p.multiplo_compra) || 1);
    const estoqueNegativo = estoque < 0;
    const semCusto = !(Number(p.custo) > 0);
    // estoque negativo = dado quebrado. Não sugiro número em cima disso — zero na
    // origem pra não haver como vazar pro pedido gerado.
    const sugerido = (sugerir && !estoqueNegativo) ? arredondaPraCima(alvoBruto, mult) : 0;

    return {
      id: p.id, sku: p.sku, nome: p.nome || p.name, unidade: p.unidade || 'UN',
      tipo: p.tipo || 'venda', custo: Number(p.custo) || 0,
      estoque, vindo, disponivel, minimo, consumoDiario, cobertura, prazo, gatilhoDias,
      multiplo: mult, sugerido, sugerir,
      estoqueNegativo, semCusto,
      bloqueado: estoqueNegativo,
    };
  });
}

// ── Fornecedor provável: o último que vendeu aquele insumo ───────────────────
// Zero coluna nova — deriva do histórico de compra e melhora sozinho conforme ela compra.
async function derivarFornecedorPorProduto() {
  const sb = window.tmSupabase;
  if (!sb) return {};
  const [itensRes, headRes] = await Promise.all([
    sb.from('pedido_compra_itens').select('insumo_id, pedido_compra_id'),
    sb.from('pedidos_compra').select('id, fornecedor_id, data_emissao, created_at'),
  ]);
  const head = {};
  (headRes.data || []).forEach(h => { head[h.id] = h; });
  const melhor = {};   // produtoId → { fornecedorId, quando }
  (itensRes.data || []).forEach(it => {
    const h = head[it.pedido_compra_id];
    if (!h || !h.fornecedor_id) return;
    const quando = String(h.data_emissao || h.created_at || '');
    if (!melhor[it.insumo_id] || quando > melhor[it.insumo_id].quando) {
      melhor[it.insumo_id] = { fornecedorId: h.fornecedor_id, quando };
    }
  });
  const out = {};
  Object.keys(melhor).forEach(pid => { out[pid] = melhor[pid].fornecedorId; });
  return out;
}

// ── Último preço pago por insumo (pré-preenche o pedido gerado) ──────────────
async function derivarUltimoPreco() {
  const sb = window.tmSupabase;
  if (!sb) return {};
  const [itensRes, headRes] = await Promise.all([
    sb.from('pedido_compra_itens').select('insumo_id, preco_compra, preco_nota, pedido_compra_id'),
    sb.from('pedidos_compra').select('id, data_emissao, created_at'),
  ]);
  const head = {};
  (headRes.data || []).forEach(h => { head[h.id] = h; });
  const melhor = {};
  (itensRes.data || []).forEach(it => {
    const h = head[it.pedido_compra_id];
    if (!h) return;
    const quando = String(h.data_emissao || h.created_at || '');
    const preco = it.preco_nota != null ? Number(it.preco_nota) : (it.preco_compra != null ? Number(it.preco_compra) : null);
    if (preco == null) return;
    if (!melhor[it.insumo_id] || quando > melhor[it.insumo_id].quando) melhor[it.insumo_id] = { preco, quando };
  });
  const out = {};
  Object.keys(melhor).forEach(pid => { out[pid] = melhor[pid].preco; });
  return out;
}

// ─── Tela ────────────────────────────────────────────────────────────────────
function SugestaoCompra({ onNav }) {   // eslint-disable-line no-unused-vars
  const prodHook = useProdutosList([]);
  const fornHook = useFornecedoresList([]);
  const [base, setBase]       = React.useState(null);
  const [fornPorProd, setFPP] = React.useState({});
  const [precoPorProd, setPPP]= React.useState({});
  const [aba, setAba]         = React.useState('insumo');   // 'insumo' | 'venda'
  const [cobertura, setCobertura] = React.useState(() => {
    const s = parseInt(localStorage.getItem('tm-cobertura-alvo'), 10);
    return COBERTURAS.indexOf(s) >= 0 ? s : COBERTURA_PADRAO;
  });
  const [sel, setSel]   = React.useState({});
  const [filtro, setFiltro] = React.useState('');   // '' | 'negativo' | 'sem-custo'
  const [busy, setBusy] = React.useState(false);
  const [msg, setMsg]   = React.useState('');
  const [carregando, setCarregando] = React.useState(true);

  React.useEffect(() => { (async () => {
    setCarregando(true);
    const [b, fpp, ppp] = await Promise.all([carregarBaseSugestao(), derivarFornecedorPorProduto(), derivarUltimoPreco()]);
    setBase(b); setFPP(fpp); setPPP(ppp); setCarregando(false);
  })(); }, []);

  const trocarCobertura = (v) => { setCobertura(v); localStorage.setItem('tm-cobertura-alvo', String(v)); };

  const fornById = {}; (fornHook.rows || []).forEach(f => { fornById[f.id] = f; });
  const prazoPorProduto = {};
  Object.keys(fornPorProd).forEach(pid => {
    const f = fornById[fornPorProd[pid]];
    const pz = f && f.prazo_entrega_dias != null ? Number(f.prazo_entrega_dias) : null;
    if (pz != null && !isNaN(pz)) prazoPorProduto[pid] = pz;
  });

  const todas = React.useMemo(
    () => calcularSugestoes(prodHook.rows || [], base, cobertura, prazoPorProduto),
    [prodHook.rows, base, cobertura, fornPorProd, fornHook.rows]   // eslint-disable-line
  );

  const daAba = todas.filter(s => (aba === 'insumo' ? s.tipo === 'insumo' : s.tipo !== 'insumo'));
  const nNegativo = daAba.filter(s => s.estoqueNegativo).length;
  const nSemCusto = daAba.filter(s => s.semCusto && s.tipo === 'insumo').length;

  const visiveis = daAba
    .filter(s => (filtro === 'negativo' ? s.estoqueNegativo : filtro === 'sem-custo' ? s.semCusto : (s.sugerir || s.estoqueNegativo)))
    .sort((a, b) => {
      if (a.bloqueado !== b.bloqueado) return a.bloqueado ? -1 : 1;
      const ca = a.cobertura == null ? 9999 : a.cobertura;
      const cb = b.cobertura == null ? 9999 : b.cobertura;
      return ca - cb;   // mais crítico primeiro
    });

  const selecionados = visiveis.filter(s => sel[s.id] && !s.bloqueado);
  const nomeForn = (pid) => { const f = fornById[fornPorProd[pid]]; return f ? f.nome : null; };

  const gerarPedidos = async () => {
    if (!selecionados.length) return;
    setBusy(true); setMsg('');
    // agrupa por fornecedor derivado; sem fornecedor conhecido vira um pedido "a definir"
    const grupos = {};
    selecionados.forEach(s => {
      const fid = fornPorProd[s.id] || '__sem__';
      if (!grupos[fid]) grupos[fid] = [];
      grupos[fid].push(s);
    });
    const criados = [];
    try {
      for (const fid of Object.keys(grupos)) {
        const linhas = grupos[fid];
        // Número da SEQUÊNCIA do banco, um por pedido. O gerarNumPC() antigo usava
        // data+hora até o minuto: este loop criava vários pedidos no mesmo minuto,
        // todos com o MESMO número. Se a RPC falhar, aborta — não inventa número.
        const rn = await window.tmDb.proximoNumeroPC();
        if (rn.error || !rn.numero) throw new Error('não consegui gerar o número do pedido: ' + ((rn.error && rn.error.message) || 'sem resposta do banco'));
        const draft = {
          numero: rn.numero,
          fornecedor_id: fid === '__sem__' ? null : fid,
          empresa_id: window.tmEmpresaId || null,
          categoria: 'Embalagens',
          status: 'rascunho',
          data_emissao: hojeIso(),
          observacoes: 'Gerado pela Sugestão de Compra',
          valor_total: linhas.reduce((a, l) => a + l.sugerido * (precoPorProd[l.id] || 0), 0),
          itens: linhas.map(l => ({ insumoId: l.id, quantidade: l.sugerido, precoCompra: precoPorProd[l.id] != null ? precoPorProd[l.id] : '' })),
        };
        const r = await window.tmDb.salvarPedidoCompra(draft);
        if (r.error) throw new Error(r.error.message || 'falha ao gravar');
        criados.push({ numero: draft.numero, forn: fid === '__sem__' ? 'sem fornecedor definido' : (fornById[fid] || {}).nome, n: linhas.length });
      }
      setSel({});
      setMsg(`${criados.length} pedido(s) de compra criados como rascunho: ` + criados.map(c => `${c.numero} (${c.forn}, ${c.n} item(ns))`).join(' · '));
    } catch (e) { setMsg('Erro: ' + String((e && e.message) || e)); }
    setBusy(false);
  };

  const fmtDias = (n) => n == null ? '—' : (n >= 999 ? '—' : `${Math.floor(n)} d`);
  const toneCobertura = (s) => {
    if (s.cobertura == null) return 'var(--tm-fg-3)';
    if (s.cobertura <= s.prazo) return 'var(--tm-danger)';
    if (s.cobertura <= s.gatilhoDias) return 'var(--tm-warning)';
    return 'var(--tm-fg-2)';
  };

  return (
    <div className="canvas">
      <PageHead title="Estoque · Sugestão de Compra" sub="O que está acabando — antes de faltar"
        right={<Button variant="primary" size="sm" icon="file-plus" disabled={busy || !selecionados.length} onClick={gerarPedidos}>
          {busy ? 'Gerando…' : `Gerar pedido de compra${selecionados.length ? ` (${selecionados.length})` : ''}`}</Button>} />

      <div className="toolbar" style={{ display: 'flex', gap: 10, alignItems: 'center', flexWrap: 'wrap', marginBottom: 12 }}>
        <div style={{ display: 'flex', gap: 6 }}>
          <Button variant={aba === 'insumo' ? 'primary' : 'secondary'} size="sm" onClick={() => { setAba('insumo'); setSel({}); setFiltro(''); }}>Insumos</Button>
          <Button variant={aba === 'venda' ? 'primary' : 'secondary'} size="sm" onClick={() => { setAba('venda'); setSel({}); setFiltro(''); }}>Produtos de venda</Button>
        </div>
        <span style={{ flex: 1 }} />
        <Field label="" >
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 12.5, color: 'var(--tm-fg-3)' }}>
            <span>Repor até</span>
            <select className="input" value={cobertura} onChange={e => trocarCobertura(Number(e.target.value))} style={{ width: 110, padding: '4px 8px' }}>
              {COBERTURAS.map(c => <option key={c} value={c}>{c} dias</option>)}
            </select>
            <span>de estoque</span>
          </div>
        </Field>
      </div>

      {aba === 'venda' && (
        <div style={{ display: 'flex', gap: 8, alignItems: 'flex-start', padding: '10px 12px', borderRadius: 8,
                      background: 'rgba(212,160,74,0.10)', border: '1px solid var(--tm-warning)', marginBottom: 12, fontSize: 12.5, lineHeight: 1.6 }}>
          <Icon name="alert-triangle" size={15} style={{ flexShrink: 0, marginTop: 2, color: 'var(--tm-warning)' }} />
          <span>O estoque de <b>produto de venda</b> ficou anos sem baixar (o "Baixa de estoque" do pedido não tinha efeito — corrigido agora),
            então o número atual está <b>inflado</b> e só se acerta com uma conferência física. A demanda desta aba vem dos <b>pedidos faturados</b>
            (essa parte é confiável), mas o <b>estoque</b> ainda não foi conferido — trate a sugestão daqui como indicação, não como verdade.
            A aba de <b>Insumos</b> não tem esse problema.</span>
        </div>
      )}

      {(nNegativo > 0 || nSemCusto > 0) && (
        <div style={{ display: 'flex', gap: 10, alignItems: 'center', flexWrap: 'wrap', marginBottom: 12, fontSize: 12.5 }}>
          <span style={{ color: 'var(--tm-fg-4)' }}>Precisa de atenção:</span>
          {nNegativo > 0 && <button onClick={() => setFiltro(filtro === 'negativo' ? '' : 'negativo')}
            style={{ cursor: 'pointer', border: '1px solid var(--tm-danger)', background: filtro === 'negativo' ? 'rgba(217,101,94,0.18)' : 'transparent',
                     color: 'var(--tm-danger)', borderRadius: 20, padding: '3px 10px', fontSize: 12 }}>
            {nNegativo} com estoque negativo</button>}
          {nSemCusto > 0 && <button onClick={() => setFiltro(filtro === 'sem-custo' ? '' : 'sem-custo')}
            style={{ cursor: 'pointer', border: '1px solid var(--tm-warning)', background: filtro === 'sem-custo' ? 'rgba(212,160,74,0.18)' : 'transparent',
                     color: 'var(--tm-warning)', borderRadius: 20, padding: '3px 10px', fontSize: 12 }}>
            {nSemCusto} insumo(s) sem custo</button>}
          {filtro && <button onClick={() => setFiltro('')} style={{ cursor: 'pointer', border: 'none', background: 'none', color: 'var(--tm-fg-3)', fontSize: 12 }}>limpar filtro</button>}
        </div>
      )}

      <Card>
        {carregando ? (
          <div style={{ padding: '28px 0', textAlign: 'center', color: 'var(--tm-fg-3)' }}>Calculando consumo…</div>
        ) : visiveis.length === 0 ? (
          <div style={{ padding: '32px 0', textAlign: 'center', color: 'var(--tm-fg-3)' }}>
            <Icon name="check-circle" size={26} style={{ color: 'var(--tm-success)', opacity: .8 }} />
            <div style={{ fontSize: 14, marginTop: 8, color: 'var(--tm-fg-1)' }}>Nada pra comprar agora</div>
            <div style={{ fontSize: 12, marginTop: 4 }}>Nenhum item desta aba entra no ponto de pedido considerando o que já está a caminho.</div>
          </div>
        ) : (
          <table className="tbl" style={{ fontSize: 12.5 }}>
            <thead><tr>
              <th style={{ width: 30 }}></th>
              <th style={{ minWidth: 190 }}>Item</th>
              <th style={{ width: 74 }} className="num right">Estoque</th>
              <th style={{ width: 82 }} className="num right">A caminho</th>
              <th style={{ width: 82 }} className="num right">Disponível</th>
              <th style={{ width: 92 }} className="num right">Consumo/dia</th>
              <th style={{ width: 96 }} className="num right">Cobertura</th>
              <th style={{ width: 92 }} className="num right">Sugerido</th>
              <th style={{ minWidth: 130 }}>Fornecedor</th>
            </tr></thead>
            <tbody>
              {visiveis.map(s => (
                <tr key={s.id}>
                  <td>{!s.bloqueado && <input type="checkbox" checked={!!sel[s.id]} onChange={e => setSel(x => ({ ...x, [s.id]: e.target.checked }))} />}</td>
                  <td>
                    <span className="ref-mono">{s.sku}</span> {s.nome}
                    {s.estoqueNegativo && <div style={{ fontSize: 10.5, color: 'var(--tm-danger)' }}>estoque negativo — corrija antes de comprar</div>}
                    {s.semCusto && s.tipo === 'insumo' && !s.estoqueNegativo && <div style={{ fontSize: 10.5, color: 'var(--tm-warning)' }}>sem custo cadastrado — o pedido sai sem preço</div>}
                  </td>
                  <td className="num right" style={{ color: s.estoqueNegativo ? 'var(--tm-danger)' : undefined }}>{s.estoque}</td>
                  <td className="num right muted">{s.vindo > 0 ? s.vindo : '—'}</td>
                  <td className="num right" style={{ fontWeight: 600 }}>{s.disponivel}</td>
                  <td className="num right muted">{s.consumoDiario > 0 ? s.consumoDiario.toFixed(1).replace('.', ',') : '—'}</td>
                  <td className="num right" style={{ color: toneCobertura(s), fontWeight: 600 }}>
                    {fmtDias(s.cobertura)}
                    <div style={{ fontSize: 10, color: 'var(--tm-fg-4)', fontWeight: 400 }}>alerta ≤ {s.gatilhoDias}d</div>
                  </td>
                  <td className="num right" style={{ fontWeight: 700 }}>
                    {s.bloqueado ? '—' : s.sugerido}
                    {!s.bloqueado && s.multiplo > 1 && <div style={{ fontSize: 10, color: 'var(--tm-fg-4)', fontWeight: 400 }}>múltiplo {s.multiplo}</div>}
                  </td>
                  <td style={{ fontSize: 12 }}>{nomeForn(s.id) || <span className="muted">a definir</span>}</td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </Card>

      {msg && <div style={{ marginTop: 12, fontSize: 12.5, color: msg.indexOf('Erro') === 0 ? 'var(--tm-danger)' : 'var(--tm-success)' }}>{msg}</div>}

      <div style={{ fontSize: 11.5, color: 'var(--tm-fg-4)', marginTop: 14, lineHeight: 1.7 }}>
        <b>Como a conta é feita.</b> <b>Consumo/dia</b> = o maior entre a média dos últimos 30 e dos últimos 90 dias
        (produção em lote faz 30 dias sozinho mentir; 90 sozinho não enxerga aceleração — o maior erra pro lado de não faltar).
        <b> Disponível</b> = estoque + o que já está em pedido de compra enviado + o que está em produção — por isso o app
        <b> não sugere comprar de novo</b> o que já vem a caminho. <b>Cobertura</b> = disponível ÷ consumo/dia, e o alerta
        dispara quando ela chega no <b>prazo do fornecedor + {FOLGA_DIAS} dias</b> de folga (prazo vem da ficha do fornecedor; sem
        preencher, {PRAZO_PADRAO_DIAS} dias). <b>Sugerido</b> = o quanto falta pra chegar em {cobertura} dias de estoque,
        arredondado pra cima no múltiplo de compra do item. Item <b>sem histórico de consumo</b> cai no estoque mínimo.
      </div>
    </div>
  );
}

Object.assign(window, { SugestaoCompra, calcularSugestoes, carregarBaseSugestao, arredondaPraCima });
