/* global React, Icon, Button, Badge, Drawer, Field, SearchableSelect, brl, fmtDate,
          somaParcelas, diferencaParcelas */

// ─── Nota de Entrada (corrente de compra · Fase 3) ───────────────────────────
// Lê o XML da NF-e do fornecedor (client-side, DOMParser), casa os itens com o
// pedido de compra e pré-preenche o check-in com quantidade e PREÇO DA NOTA —
// que é o valor fiscal, o que manda no custo (decisão travada no DESIGN_compra.md).
//
// ⚠️ O PONTO QUE DÓI: o `cProd` do XML é o código DO FORNECEDOR, não o SKU dela.
// O casamento automático falharia toda semana. Por isso existe o DE-PARA
// PERSISTENTE (fornecedor_produto_codigos): ela mapeia uma vez por item/fornecedor
// e o app guarda — nas próximas notas daquele fornecedor casa sozinho.

// ── Parser da NF-e ───────────────────────────────────────────────────────────
// Namespace-agnóstico (getElementsByTagNameNS('*', …)): o XML da NF-e vem com o
// namespace portalfiscal e às vezes com prefixo, então nunca casamos por tag crua.
function parseNFeXml(texto) {
  let doc;
  try { doc = new DOMParser().parseFromString(texto, 'text/xml'); }
  catch (e) { return { error: 'Não consegui ler o arquivo como XML.' }; }
  if (doc.getElementsByTagName('parsererror')[0]) return { error: 'XML inválido — o arquivo parece corrompido.' };

  const els = (root, tag) => Array.from((root || doc).getElementsByTagNameNS('*', tag));
  const txt = (root, tag) => { const e = els(root, tag)[0]; return e ? String(e.textContent || '').trim() : ''; };

  const infNFe = els(doc, 'infNFe')[0];
  if (!infNFe) return { error: 'Não parece uma NF-e: não encontrei o bloco infNFe.' };

  // chave: atributo Id = "NFe" + 44 dígitos (fallback: <chNFe> do protocolo)
  const idAttr = String(infNFe.getAttribute('Id') || '');
  const chave = (idAttr.replace(/^NFe/i, '') || txt(doc, 'chNFe')).trim();

  const emit = els(doc, 'emit')[0];
  const ide  = els(doc, 'ide')[0];
  const icms = els(doc, 'ICMSTot')[0];

  const num = (v) => { const n = parseFloat(String(v || '').replace(',', '.')); return isNaN(n) ? 0 : n; };
  const dhEmi = txt(ide, 'dhEmi') || txt(ide, 'dEmi');

  const itens = els(doc, 'det').map((det, i) => {
    const prod = els(det, 'prod')[0];
    if (!prod) return null;
    return {
      n:        det.getAttribute('nItem') || String(i + 1),
      cProd:    txt(prod, 'cProd'),
      xProd:    txt(prod, 'xProd'),
      ncm:      txt(prod, 'NCM'),
      uCom:     txt(prod, 'uCom') || 'UN',
      qCom:     num(txt(prod, 'qCom')),
      vUnCom:   num(txt(prod, 'vUnCom')),
      vProd:    num(txt(prod, 'vProd')),
    };
  }).filter(Boolean);

  if (!itens.length) return { error: 'A NF-e não tem itens legíveis (bloco det/prod vazio).' };

  return {
    chave,
    numero: txt(ide, 'nNF'),
    serie:  txt(ide, 'serie'),
    dataEmissao: dhEmi ? dhEmi.slice(0, 10) : '',
    emitCnpj: txt(emit, 'CNPJ') || txt(emit, 'CPF'),
    emitNome: txt(emit, 'xNome'),
    valorProdutos: num(txt(icms, 'vProd')),
    valorFrete:    num(txt(icms, 'vFrete')),
    valorDesconto: num(txt(icms, 'vDesc')),
    valorTotal: num(txt(icms, 'vNF')),
    itens,
  };
}

// Só dígitos — CNPJ vem formatado no cadastro e cru no XML.
const soDigitos = (s) => String(s || '').replace(/[^0-9]/g, '');

// ── De-para persistente ──────────────────────────────────────────────────────
async function carregarDePara(fornecedorId) {
  if (!window.tmSupabase || !fornecedorId) return {};
  const { data, error } = await window.tmSupabase
    .from('fornecedor_produto_codigos').select('codigo_fornecedor, produto_id')
    .eq('fornecedor_id', fornecedorId);
  if (error) return {};
  const m = {};
  (data || []).forEach(r => { m[String(r.codigo_fornecedor)] = r.produto_id; });
  return m;
}

async function salvarDePara(fornecedorId, linhas) {
  if (!window.tmSupabase || !fornecedorId || !linhas.length) return { error: null };
  const rows = linhas.map(l => ({
    fornecedor_id: fornecedorId, codigo_fornecedor: String(l.cProd),
    produto_id: l.produtoId, descricao_fornecedor: l.xProd || null,
    updated_at: new Date().toISOString(),
  }));
  const { error } = await window.tmSupabase.from('fornecedor_produto_codigos')
    .upsert(rows, { onConflict: 'fornecedor_id,codigo_fornecedor' });
  return { error };
}

// Todos os títulos já ligados a este pedido (não só o primeiro): é o que permite
// avisar com precisão e limpar órfão se um insert falhar no meio.
async function titulosDoPedido(pedidoId) {
  if (!window.tmSupabase || !pedidoId) return [];
  const { data } = await window.tmSupabase.from('contas_pagar')
    .select('id, referencia, valor, status, vencimento, parcela').eq('pedido_compra_id', pedidoId);
  return data || [];
}

async function contaPagarDoPedido(pedidoId) {
  const t = await titulosDoPedido(pedidoId);
  return t[0] || null;
}

// nome da conta bancária → id (o mesmo resolveContaId do faturamento da venda).
// Não casou → null ("Sem conta"), nunca inventa vínculo.
async function mapaContasPorNome() {
  const m = {};
  if (!window.tmSupabase) return m;
  try {
    const { data } = await window.tmSupabase.from('contas_bancarias').select('id,nome').eq('situacao', 'Ativa');
    (data || []).forEach(c => { m[String(c.nome || '').trim().toLowerCase()] = c.id; });
  } catch (e) { /* sem contas → tudo Sem conta */ }
  return m;
}

const isoDeBR = (br) => {
  const m = String(br || '').match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
  return m ? `${m[3]}-${m[2]}-${m[1]}` : null;
};

// ── Nudge: gerar conta(s) a pagar do pedido ──────────────────────────────────
// Com PARCELAS → N títulos (um por parcela, com vencimento e forma de cada uma).
// Sem parcelas → 1 título, como sempre foi (fornecedor que não parcela).
//
// IDEMPOTENTE: se QUALQUER título já existir pro pedido, avisa e não cria nada.
// NUNCA PARCIAL: as N linhas vão num único insert (atômico no Postgres) e, se
// ainda assim sobrar algo depois de um erro, os órfãos são apagados — melhor
// nenhum título do que meio carnê no contas a pagar.
async function gerarContaPagar(pedido, fornecedorNome, nota) {
  const jaTem = await titulosDoPedido(pedido.id);
  if (jaTem.length) return { jaExiste: jaTem[0], quantos: jaTem.length };

  const parcelas = Array.isArray(pedido.parcelas) ? pedido.parcelas.filter(p => p) : [];
  const totalPedido = Number(pedido.valor_total) || 0;
  const totalNota   = Number(nota && nota.valorTotal) || 0;

  // As parcelas foram montadas sobre o total DO PEDIDO — é contra ele que a soma
  // tem de fechar. Não fechando, não cria: carnê torto é pior que título único.
  if (parcelas.length) {
    const soma = window.somaParcelas(parcelas);
    if (Math.abs(soma - totalPedido) > 0.005) {
      return { error: { message: `As parcelas somam R$ ${brl(soma)} e o total do pedido é R$ ${brl(totalPedido)}. Ajuste as parcelas no pedido antes de gerar.` } };
    }
  }

  const contaMap = await mapaContasPorNome();
  const resolveConta = (nome) => nome ? (contaMap[String(nome).trim().toLowerCase()] || null) : null;
  const obsNf = nota && nota.chave ? `NF-e ${nota.chave}` : null;
  const vencPadrao = (nota && nota.dataEmissao) || pedido.data_recebimento || null;

  const rows = parcelas.length
    ? parcelas.map((par, i) => ({
        referencia: `${pedido.numero}/${i + 1}`,
        fornecedor: fornecedorNome || null,
        categoria: pedido.categoria || 'Embalagens',
        vencimento: isoDeBR(par.venc) || vencPadrao,
        valor: Number(par.valor) || 0,
        parcela: i + 1,
        status: 'Em aberto',
        forma_pagamento: par.forma || 'Boleto',
        conta_id: resolveConta(par.conta),
        pedido_compra_id: pedido.id,
        observacoes: obsNf,
      }))
    : [{
        referencia: nota && nota.numero ? `NF ${nota.numero} · ${pedido.numero}` : `${pedido.numero}`,
        fornecedor: fornecedorNome || null,
        categoria: pedido.categoria || 'Embalagens',
        vencimento: vencPadrao,
        valor: totalNota || totalPedido,
        parcela: null,
        status: 'Em aberto',
        forma_pagamento: 'Boleto',
        conta_id: null,
        pedido_compra_id: pedido.id,
        observacoes: obsNf,
      }];

  const { error } = await window.tmSupabase.from('contas_pagar').insert(rows);
  if (error) {
    // Insert de array é atômico, mas se algo escapar não deixo meio carnê no ar.
    try {
      const sobrou = await titulosDoPedido(pedido.id);
      if (sobrou.length) await window.tmSupabase.from('contas_pagar').delete().eq('pedido_compra_id', pedido.id);
    } catch (e) { /* nada a fazer além de reportar o erro original */ }
    return { error };
  }

  const soma = rows.reduce((a, r) => a + (Number(r.valor) || 0), 0);
  return { criado: { n: rows.length, total: Math.round(soma * 100) / 100,
    parcelado: parcelas.length > 0,
    divergeDaNota: totalNota > 0 && Math.abs(totalNota - soma) > 0.005 ? { nota: totalNota, titulos: Math.round(soma * 100) / 100 } : null } };
}

// ─── Drawer: importar a nota, casar os itens, registrar ──────────────────────
function NotaEntradaForm({ pedido, itens, prodById, insumos, fornecedor, onClose, onRegistrada, onIrParaCheckin }) {
  const [nota, setNota]     = React.useState(null);     // resultado do parse
  const [erro, setErro]     = React.useState('');
  const [mapa, setMapa]     = React.useState({});       // cProd → produtoId (de-para salvo)
  const [escolha, setEscolha] = React.useState({});     // cProd → produtoId (nesta tela)
  const [busy, setBusy]     = React.useState(false);
  const [passo, setPasso]   = React.useState('importar');  // importar | registrada
  const [cp, setCp]         = React.useState(undefined);   // undefined=?, null=nenhuma, obj=existe
  const [cpMsg, setCpMsg]   = React.useState('');
  const [cpQuantos, setCpQuantos] = React.useState(0);
  const inputRef = React.useRef(null);

  React.useEffect(() => { (async () => {
    setMapa(await carregarDePara(pedido.fornecedor_id));
    const ts = await titulosDoPedido(pedido.id);
    setCp(ts[0] || null); setCpQuantos(ts.length);
  })(); }, [pedido.id]);   // eslint-disable-line

  const insumoOpts = (insumos || []).map(p => ({ value: p.id, label: `${p.sku} · ${p.nome || p.name}` }));

  // Parcelas do pedido: definem se o nudge cria 1 titulo ou N, e travam o botao
  // quando a soma nao fecha com o total (carne torto e pior que titulo unico).
  const parcelasDoPedido = Array.isArray(pedido.parcelas) ? pedido.parcelas.filter(x => x) : [];
  const somaParcPedido   = parcelasDoPedido.length ? window.somaParcelas(parcelasDoPedido) : 0;
  const difParcPedido    = parcelasDoPedido.length ? window.diferencaParcelas(Number(pedido.valor_total) || 0, parcelasDoPedido) : 0;
  const parcelasNaoFecham = parcelasDoPedido.length > 0 && Math.abs(difParcPedido) > 0.005;

  // casamento: de-para salvo → SKU igual ao cProd → escolha manual
  const casarAuto = (it) => {
    if (mapa[it.cProd]) return { produtoId: mapa[it.cProd], via: 'de-para' };
    const porSku = (insumos || []).find(p => String(p.sku || '').toLowerCase() === String(it.cProd || '').toLowerCase());
    if (porSku) return { produtoId: porSku.id, via: 'sku' };
    return { produtoId: '', via: null };
  };
  const resolvido = (it) => {
    if (escolha[it.cProd] !== undefined) return escolha[it.cProd];
    return casarAuto(it).produtoId;
  };

  const lerArquivo = (file) => {
    if (!file) return;
    setErro('');
    const fr = new FileReader();
    fr.onload = () => {
      const r = parseNFeXml(String(fr.result || ''));
      if (r.error) { setErro(r.error); setNota(null); return; }
      setNota(r);
    };
    fr.onerror = () => setErro('Falha ao ler o arquivo.');
    fr.readAsText(file, 'UTF-8');
  };

  const cnpjBate = nota && fornecedor && fornecedor.cnpj
    ? soDigitos(nota.emitCnpj) === soDigitos(fornecedor.cnpj) : null;

  const naoCasados = nota ? nota.itens.filter(it => !resolvido(it)) : [];
  const novosNoMapa = nota ? nota.itens.filter(it => {
    const pid = resolvido(it);
    return pid && mapa[it.cProd] !== pid;
  }) : [];

  // itens do PEDIDO por insumo → onde gravar preco_nota e o que sugerir no check-in
  const itemDoPedidoPorInsumo = {};
  (itens || []).forEach(it => { itemDoPedidoPorInsumo[it.insumoId] = it; });

  const registrar = async () => {
    if (!nota) return;
    if (naoCasados.length) { setErro(`Faltam ${naoCasados.length} item(ns) sem insumo escolhido.`); return; }
    setBusy(true); setErro('');
    try {
      // 1) guarda o de-para (é isto que faz a próxima nota casar sozinha)
      const paraSalvar = nota.itens.map(it => ({ cProd: it.cProd, xProd: it.xProd, produtoId: resolvido(it) }))
        .filter(l => l.produtoId);
      const rSave = await salvarDePara(pedido.fornecedor_id, paraSalvar);
      if (rSave.error) throw new Error('Falha ao salvar o de-para: ' + (rSave.error.message || rSave.error));

      // 2) grava o preço da NOTA nos itens do pedido (é o que vale pro custo)
      for (const it of nota.itens) {
        const alvo = itemDoPedidoPorInsumo[resolvido(it)];
        if (!alvo) continue;   // item da nota que não está no pedido — só informa, não inventa linha
        await window.tmSupabase.from('pedido_compra_itens')
          .update({ preco_nota: it.vUnCom }).eq('id', alvo.id);
      }

      // 3) referencia a nota no pedido
      await window.tmSupabase.from('pedidos_compra').update({
        nf_entrada_chave: nota.chave || null, nf_entrada_numero: nota.numero || null,
      }).eq('id', pedido.id);

      setMapa(m => { const n = { ...m }; paraSalvar.forEach(l => { n[l.cProd] = l.produtoId; }); return n; });
      setPasso('registrada');
      if (onRegistrada) onRegistrada();
    } catch (e) { setErro(String((e && e.message) || e)); }
    setBusy(false);
  };

  const gerar = async () => {
    setBusy(true); setCpMsg('');
    const r = await gerarContaPagar(pedido, fornecedor && fornecedor.nome, nota);
    setBusy(false);
    if (r.error) { setCpMsg('Erro: ' + (r.error.message || r.error) + ' Nada foi criado.'); return; }
    if (r.jaExiste) {
      setCp(r.jaExiste); setCpQuantos(r.quantos || 1);
      setCpMsg(`Este pedido já tem ${r.quantos > 1 ? r.quantos + ' títulos' : 'conta a pagar'} — não dupliquei.`);
      return;
    }
    const ts = await titulosDoPedido(pedido.id);
    setCp(ts[0] || null); setCpQuantos(ts.length);
    const c = r.criado || {};
    setCpMsg(`${c.n > 1 ? c.n + ' títulos criados' : 'Conta a pagar criada'} (R$ ${brl(c.total)}).`
      + (c.divergeDaNota ? ` Atenção: a nota é de R$ ${brl(c.divergeDaNota.nota)} e os títulos somam R$ ${brl(c.divergeDaNota.titulos)} — confira.` : ''));
  };

  // quantidades da nota, por item do pedido → pré-preenche o check-in
  const qtdSugeridas = () => {
    const q = {};
    if (!nota) return q;
    nota.itens.forEach(it => {
      const alvo = itemDoPedidoPorInsumo[resolvido(it)];
      if (alvo) q[alvo.id] = it.qCom;
    });
    return q;
  };

  return (
    <Drawer open={true} width={980} title={`Nota de entrada · ${pedido.numero}`}
      subtitle="Importe o XML da NF-e do fornecedor — as quantidades e o preço da nota alimentam o check-in"
      onClose={onClose}
      footer={passo === 'importar' ? (<><span style={{ flex: 1 }} />
        <Button variant="secondary" size="sm" onClick={onClose}>Cancelar</Button>
        <Button variant="primary" size="sm" icon="check" onClick={registrar} disabled={busy || !nota}>{busy ? 'Registrando…' : 'Registrar nota'}</Button></>)
        : (<><span style={{ flex: 1 }} />
        <Button variant="secondary" size="sm" onClick={onClose}>Fechar</Button>
        <Button variant="primary" size="sm" icon="package-check" onClick={() => onIrParaCheckin(qtdSugeridas())}>Receber os itens desta nota</Button></>)}>

      {passo === 'importar' && (<>
        {!nota && (
          <div onClick={() => inputRef.current && inputRef.current.click()}
            onDragOver={e => e.preventDefault()}
            onDrop={e => { e.preventDefault(); lerArquivo(e.dataTransfer.files && e.dataTransfer.files[0]); }}
            style={{ border: '2px dashed var(--tm-line-2)', borderRadius: 'var(--tm-radius-md)', padding: '38px 20px',
                     textAlign: 'center', cursor: 'pointer', color: 'var(--tm-fg-3)' }}>
            <Icon name="file-up" size={26} style={{ opacity: .7 }} />
            <div style={{ marginTop: 10, fontSize: 14, color: 'var(--tm-fg-1)' }}>Solte o XML da NF-e aqui ou clique para escolher</div>
            <div style={{ fontSize: 12, marginTop: 4 }}>O arquivo é lido no seu navegador — nada é enviado pra fora.</div>
          </div>
        )}
        <input ref={inputRef} type="file" accept=".xml,text/xml,application/xml" style={{ display: 'none' }}
          onChange={e => lerArquivo(e.target.files && e.target.files[0])} />

        {nota && (<>
          <div className="field-grid-4" style={{ marginBottom: 6 }}>
            <div><div style={{ fontSize: 11, color: 'var(--tm-fg-4)' }}>Emitente</div><div>{nota.emitNome || '—'}</div></div>
            <div><div style={{ fontSize: 11, color: 'var(--tm-fg-4)' }}>NF-e nº</div><div>{nota.numero || '—'}{nota.serie ? ` / ${nota.serie}` : ''}</div></div>
            <div><div style={{ fontSize: 11, color: 'var(--tm-fg-4)' }}>Emissão</div><div>{nota.dataEmissao ? (fmtDate(nota.dataEmissao) || nota.dataEmissao) : '—'}</div></div>
            <div><div style={{ fontSize: 11, color: 'var(--tm-fg-4)' }}>Total da nota</div><div style={{ fontWeight: 600 }}>R$ {brl(nota.valorTotal)}</div></div>
          </div>
          {cnpjBate === false && (
            <div style={{ display: 'flex', gap: 8, alignItems: 'center', fontSize: 12.5, color: 'var(--tm-warning)', margin: '8px 0' }}>
              <Icon name="alert-triangle" size={15} />
              <span>O CNPJ do emitente ({nota.emitCnpj}) é diferente do cadastro de <b>{fornecedor && fornecedor.nome}</b>. Confira se a nota é deste pedido.</span>
            </div>
          )}

          <div style={{ fontSize: 10.5, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '.08em', color: 'var(--tm-fg-4)', margin: '14px 0 6px' }}>
            Itens da nota · casar com os insumos
          </div>
          <table className="tbl" style={{ fontSize: 12.5 }}>
            <thead><tr>
              <th style={{ width: 110, whiteSpace: 'nowrap' }}>Cód. forn.</th>
              <th style={{ minWidth: 170 }}>Descrição na nota</th>
              <th style={{ width: 62 }} className="num right">Qtd</th>
              <th style={{ width: 92, whiteSpace: 'nowrap' }} className="num right">Vlr unit.</th>
              <th style={{ minWidth: 210 }}>Insumo (o seu)</th>
              <th style={{ width: 96 }}>Casou por</th>
            </tr></thead>
            <tbody>
              {nota.itens.map(it => {
                const auto = casarAuto(it);
                const pid  = resolvido(it);
                const noPedido = !!itemDoPedidoPorInsumo[pid];
                return (
                  <tr key={it.cProd + it.n}>
                    <td style={{ whiteSpace: 'nowrap' }}><span className="ref-mono">{it.cProd || '—'}</span></td>
                    <td>{it.xProd || '—'}
                      {pid && !noPedido && <div style={{ fontSize: 10.5, color: 'var(--tm-warning)' }}>não está neste pedido</div>}
                    </td>
                    <td className="num right">{it.qCom}</td>
                    <td className="num right" style={{ whiteSpace: 'nowrap' }}>R$ {brl(it.vUnCom)}</td>
                    <td>
                      <SearchableSelect value={pid} onChange={v => setEscolha(s => ({ ...s, [it.cProd]: v }))}
                        options={insumoOpts} placeholder="Buscar insumo…" />
                    </td>
                    <td style={{ fontSize: 11 }}>
                      {!pid ? <span style={{ color: 'var(--tm-danger)' }}>escolher</span>
                        : escolha[it.cProd] !== undefined ? <span style={{ color: 'var(--tm-info)' }}>você agora</span>
                        : auto.via === 'de-para' ? <span style={{ color: 'var(--tm-success)' }}>de-para</span>
                        : <span style={{ color: 'var(--tm-fg-3)' }}>SKU igual</span>}
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>

          <div style={{ fontSize: 11.5, color: 'var(--tm-fg-4)', marginTop: 10, lineHeight: 1.6 }}>
            O <b>código do fornecedor</b> na nota não é o seu SKU — por isso você casa uma vez e o app <b>guarda o de-para</b>:
            nas próximas notas de <b>{(fornecedor && fornecedor.nome) || 'deste fornecedor'}</b> esses itens casam sozinhos.
            {novosNoMapa.length > 0 && <> Serão gravados <b>{novosNoMapa.length}</b> novo(s) vínculo(s).</>}
          </div>
          {erro && <div style={{ fontSize: 12.5, color: 'var(--tm-danger)', marginTop: 10 }}>{erro}</div>}
        </>)}
        {!nota && erro && <div style={{ fontSize: 12.5, color: 'var(--tm-danger)', marginTop: 10 }}>{erro}</div>}
      </>)}

      {passo === 'registrada' && nota && (<>
        <div style={{ display: 'flex', gap: 10, alignItems: 'center', padding: '12px 14px', borderRadius: 8,
                      background: 'rgba(91,177,122,0.10)', border: '1px solid var(--tm-success)', marginBottom: 16 }}>
          <Icon name="check-circle" size={18} style={{ color: 'var(--tm-success)' }} />
          <div style={{ fontSize: 13 }}>
            Nota <b>{nota.numero}</b> registrada no pedido · de-para guardado ·
            o <b>preço da nota</b> foi gravado nos itens e já vale pro custo no check-in.
          </div>
        </div>

        {/* NUDGE — sugerido à vista, nunca automático e nunca escondido num menu */}
        <div style={{ padding: '16px 18px', borderRadius: 10, border: '1px solid var(--tm-line-2)', background: 'var(--tm-bg-2)' }}>
          <div style={{ fontSize: 14, fontWeight: 600, marginBottom: 4 }}>
            {parcelasDoPedido.length > 1 ? `Gerar as ${parcelasDoPedido.length} contas a pagar deste pedido?` : 'Gerar conta a pagar deste pedido?'}
          </div>
          <div style={{ fontSize: 12.5, color: 'var(--tm-fg-3)', lineHeight: 1.6 }}>
            {cp
              ? <>Este pedido <b>já tem</b> {cpQuantos > 1 ? <>{cpQuantos} títulos</> : <>um título</>} (<b>{cp.referencia}</b> · R$ {brl(cp.valor)} · {cp.status}). Não vou duplicar.</>
              : parcelasDoPedido.length
                ? <>Cria <b>{parcelasDoPedido.length} títulos</b> em <b>Financeiro › Contas a pagar</b> — um por parcela, com o vencimento de cada uma —
                    para <b>{(fornecedor && fornecedor.nome) || '—'}</b>, categoria <b>{pedido.categoria || 'Embalagens'}</b> (a do pedido, entra como CMV).
                    Total <b>R$ {brl(somaParcPedido)}</b>. Se você já lançou à mão, ignore.</>
                : <>Cria <b>um título</b> em <b>Financeiro › Contas a pagar</b>: fornecedor <b>{(fornecedor && fornecedor.nome) || '—'}</b>,
                    categoria <b>{pedido.categoria || 'Embalagens'}</b> (a do pedido, entra como CMV),
                    valor <b>R$ {brl(nota.valorTotal)}</b> (o da nota), vencimento <b>{nota.dataEmissao ? (fmtDate(nota.dataEmissao) || nota.dataEmissao) : '—'}</b>.
                    Se você já lançou à mão, ignore.</>}
          </div>
          {parcelasDoPedido.length > 0 && !cp && (
            <table className="tbl" style={{ fontSize: 12, marginTop: 10 }}>
              <thead><tr><th style={{ width: 34 }}>Nº</th><th>Vencimento</th><th className="num right">Valor</th><th>Forma</th><th>Conta</th></tr></thead>
              <tbody>{parcelasDoPedido.map((par, i) => (
                <tr key={i}><td>{i + 1}</td><td>{par.venc || '—'}</td><td className="num right">R$ {brl(par.valor)}</td>
                  <td>{par.forma || 'Boleto'}</td><td>{par.conta || <span className="muted">sem conta</span>}</td></tr>))}</tbody>
            </table>
          )}
          {!cp && parcelasNaoFecham && (
            <div style={{ fontSize: 12.5, color: 'var(--tm-danger)', marginTop: 10, display: 'flex', gap: 6, alignItems: 'center' }}>
              <Icon name="alert-triangle" size={14} />
              As parcelas somam R$ {brl(somaParcPedido)} e o total do pedido é R$ {brl(Number(pedido.valor_total) || 0)} —
              diferença de R$ {brl(Math.abs(difParcPedido))}. Ajuste as parcelas no pedido antes de gerar.
            </div>
          )}
          {!cp && <div style={{ marginTop: 12 }}>
            <Button variant="primary" size="sm" icon="file-plus" onClick={gerar} disabled={busy || parcelasNaoFecham}>
              {busy ? 'Gerando…' : (parcelasDoPedido.length > 1 ? `Gerar ${parcelasDoPedido.length} contas a pagar` : 'Gerar conta a pagar')}</Button>
          </div>}
          {cpMsg && <div style={{ fontSize: 12.5, marginTop: 10, color: cpMsg.indexOf('Erro') === 0 ? 'var(--tm-danger)' : 'var(--tm-success)' }}>{cpMsg}</div>}
        </div>
      </>)}
    </Drawer>
  );
}

Object.assign(window, { parseNFeXml, carregarDePara, salvarDePara, contaPagarDoPedido, titulosDoPedido, gerarContaPagar, mapaContasPorNome, NotaEntradaForm });
