
// Compras — Ordens de Compra + Cotações
//
// Fecha o fluxo que começa em Cotacoes.jsx:
//   ... Escolher fornecedor -> Gerar Ordem de Compra -> fornecedor confirma
//   pelo link -> a Edge Function 'oc-publica' lança a conta a pagar no
//   Financeiro (transactions, despesa Pendente).
//
// A OC guarda SNAPSHOT do fornecedor/evento na criação: documento enviado
// não pode mudar de conteúdo porque alguém editou o cadastro depois.

const OC_STATUS_VARIANT = {
  Rascunho: 'default', Enviada: 'primary', Confirmada: 'success',
  Recusada: 'danger', Cancelada: 'default',
};

const FORMAS_PAGAMENTO = ['PIX', 'Transferência', 'Boleto', 'Cartão', 'Dinheiro'];

const dataBR = (d) => d ? new Date(String(d).slice(0, 10) + 'T00:00:00').toLocaleDateString('pt-BR') : '—';

// Soma dos itens — fonte única do valor total, na tela e no PDF.
function somaItens(itens) {
  return (itens || []).reduce((s, it) => s + (Number(it.qtd) || 0) * (Number(it.valor_unit) || 0), 0);
}

// Texto padronizado enviado ao fornecedor junto com o PDF
function mensagemOC({ oc, link }) {
  return [
    `Olá, ${oc.fornecedor_contato || oc.fornecedor_nome}! Aqui é da Promoup.`,
    '',
    `Segue a *Ordem de Compra ${oc.numero}*:`,
    '',
    oc.evento_nome ? `Evento: ${oc.evento_nome}${oc.evento_data ? ` — ${dataBR(oc.evento_data)}` : ''}` : '',
    oc.evento_local ? `Local: ${oc.evento_local}` : '',
    oc.descricao ? `Serviço: ${oc.descricao}` : '',
    `Valor total: *${fmtBRL(oc.valor_total)}*`,
    oc.data_servico ? `Prazo de execução: ${dataBR(oc.data_servico)}` : '',
    `Pagamento: ${oc.forma_pagamento || 'PIX'}${oc.prazo_pagamento ? ` — ${oc.prazo_pagamento}` : ''}`,
    '',
    'Confirme ou recuse o serviço por aqui:',
    link,
  ].join('\n').replace(/\n{3,}/g, '\n\n');
}

// Gera o PDF como Blob (para subir no Storage e mandar no WhatsApp).
// Reusa o mesmo preparo do renderPDF de EventReports (mountPDFClone +
// pdfOptions): o template fica invisível dentro da tela, então precisa ser
// clonado num wrapper visível-mas-atrás e normalizado para a largura da
// folha — senão o html2canvas produz uma página em branco ou cortada.
async function ocPdfBlob(node) {
  if (!node || !window.html2pdf || !window.mountPDFClone) return null;
  const mounted = await window.mountPDFClone(node);
  if (!mounted) return null;
  const { wrapper, clone } = mounted;
  try {
    return await window.html2pdf().set(window.pdfOptions()).from(clone).outputPdf('blob');
  } catch (err) {
    console.error('[oc-pdf] falha ao gerar:', err);
    return null;
  } finally {
    if (wrapper.parentNode) document.body.removeChild(wrapper);
  }
}

// ---------------------------------------------------------------------
// Template do PDF da OC
// ---------------------------------------------------------------------
function OCPDFTemplate({ oc, innerRef }) {
  if (!oc) return null;
  const b = oc.dados_bancarios || {};
  const itens = oc.itens || [];
  const td = { padding: '7px 9px', borderBottom: '1px solid #E2E8F0', fontSize: 11, color: '#334155' };
  const th = { padding: '7px 9px', borderBottom: '2px solid #CBD5E1', fontSize: 9, fontWeight: 700, color: '#64748B', textTransform: 'uppercase', letterSpacing: '0.05em', textAlign: 'left' };
  const campo = (k, v) => (
    <div style={{ padding: '7px 10px', border: '1px solid #E2E8F0', borderRadius: 6 }}>
      <div style={{ fontSize: 8, fontWeight: 700, color: '#94A3B8', textTransform: 'uppercase', letterSpacing: '0.06em' }}>{k}</div>
      <div style={{ fontSize: 11, fontWeight: 600, color: '#0F172A', marginTop: 2 }}>{v || '—'}</div>
    </div>
  );

  return (
    <div ref={innerRef} style={{ position: 'absolute', left: -99999, top: 0, opacity: 0, width: 760, background: '#fff', padding: 34, fontFamily: 'Inter, sans-serif', color: '#0F172A' }}>
      {/* Cabeçalho */}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', borderBottom: '3px solid #EA6B00', paddingBottom: 14, marginBottom: 18 }}>
        <div>
          <img src="logo.png" alt="Promoup" style={{ height: 42, marginBottom: 6 }} />
          <div style={{ fontSize: 10, color: '#64748B' }}>Promoup Marketing &amp; Eventos</div>
        </div>
        <div style={{ textAlign: 'right' }}>
          <div style={{ fontSize: 10, fontWeight: 700, color: '#94A3B8', textTransform: 'uppercase', letterSpacing: '0.1em' }}>Ordem de Compra</div>
          <div style={{ fontSize: 22, fontWeight: 800, color: '#EA6B00', letterSpacing: '-0.02em' }}>{oc.numero}</div>
          <div style={{ fontSize: 10, color: '#64748B', marginTop: 2 }}>Emitida em {dataBR(oc.created_at)}</div>
        </div>
      </div>

      {/* Fornecedor / Cliente / Evento */}
      <div className="pdf-keep" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginBottom: 8 }}>
        {campo('Fornecedor', oc.fornecedor_nome)}
        {campo('Contato', [oc.fornecedor_contato, oc.fornecedor_telefone].filter(Boolean).join(' · '))}
      </div>
      <div className="pdf-keep" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 8, marginBottom: 18 }}>
        {campo('Cliente', oc.cliente_nome)}
        {campo('Evento', oc.evento_nome)}
        {campo('Data do evento', dataBR(oc.evento_data))}
      </div>

      {/* Serviço */}
      <div style={{ fontSize: 10, fontWeight: 800, color: '#94A3B8', textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: 6 }}>Serviço contratado</div>
      {oc.descricao && (
        <div style={{ fontSize: 11, color: '#334155', lineHeight: 1.6, background: '#F8FAFC', padding: '9px 11px', borderRadius: 6, borderLeft: '3px solid #CBD5E1', marginBottom: 10, whiteSpace: 'pre-wrap' }}>
          {oc.descricao}
        </div>
      )}

      {itens.length > 0 && (
        <table style={{ width: '100%', borderCollapse: 'collapse', marginBottom: 12 }}>
          <thead>
            <tr>
              <th style={th}>Descrição</th>
              <th style={{ ...th, textAlign: 'right', width: 70 }}>Qtd</th>
              <th style={{ ...th, textAlign: 'right', width: 95 }}>Valor unit.</th>
              <th style={{ ...th, textAlign: 'right', width: 95 }}>Subtotal</th>
            </tr>
          </thead>
          <tbody>
            {itens.map((it, i) => (
              <tr key={i}>
                <td style={td}>{it.descricao || '—'}</td>
                <td style={{ ...td, textAlign: 'right' }}>{it.qtd || 0}{it.unidade ? ` ${it.unidade}` : ''}</td>
                <td style={{ ...td, textAlign: 'right' }}>{fmtBRL(it.valor_unit)}</td>
                <td style={{ ...td, textAlign: 'right', fontWeight: 700 }}>{fmtBRL((Number(it.qtd) || 0) * (Number(it.valor_unit) || 0))}</td>
              </tr>
            ))}
          </tbody>
        </table>
      )}

      <div className="pdf-keep" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', background: '#FFF7ED', border: '1px solid #FED7AA', borderRadius: 8, padding: '12px 16px', marginBottom: 18 }}>
        <span style={{ fontSize: 11, fontWeight: 700, color: '#9A3412', textTransform: 'uppercase', letterSpacing: '0.06em' }}>Valor total</span>
        <span style={{ fontSize: 22, fontWeight: 800, color: '#EA6B00' }}>{fmtBRL(oc.valor_total)}</span>
      </div>

      {/* Condições */}
      <div className="pdf-keep" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 8, marginBottom: 18 }}>
        {campo('Prazo de execução', dataBR(oc.data_servico))}
        {campo('Forma de pagamento', oc.forma_pagamento)}
        {campo('Prazo de pagamento', oc.prazo_pagamento)}
      </div>

      {/* Dados bancários */}
      {(b.banco || b.pix_chave) && (
        <div className="pdf-keep" style={{ marginBottom: 18 }}>
          <div style={{ fontSize: 10, fontWeight: 800, color: '#94A3B8', textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: 6 }}>Dados para pagamento</div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
            {campo('Favorecido', b.favorecido)}
            {campo('CPF/CNPJ', b.favorecido_doc)}
            {campo('Banco / Agência / Conta', [b.banco, b.agencia, b.conta && `${b.conta} (${b.tipo_conta || 'Corrente'})`].filter(Boolean).join(' · '))}
            {campo(`PIX${b.pix_tipo ? ` (${b.pix_tipo})` : ''}`, b.pix_chave)}
          </div>
        </div>
      )}

      {oc.observacoes && (
        <div className="pdf-keep" style={{ marginBottom: 18 }}>
          <div style={{ fontSize: 10, fontWeight: 800, color: '#94A3B8', textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: 6 }}>Observações</div>
          <div style={{ fontSize: 11, color: '#334155', lineHeight: 1.6, whiteSpace: 'pre-wrap' }}>{oc.observacoes}</div>
        </div>
      )}

      <div style={{ borderTop: '1px solid #E2E8F0', paddingTop: 12, fontSize: 9, color: '#94A3B8', lineHeight: 1.6 }}>
        A confirmação deste documento pelo fornecedor, por escrito ou pelo link enviado, caracteriza aceite das condições acima.<br />
        {oc.status === 'Confirmada' && oc.responded_at
          ? `CONFIRMADA pelo fornecedor em ${new Date(oc.responded_at).toLocaleString('pt-BR')}.`
          : 'Aguardando confirmação do fornecedor.'}
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------
// Módulo Compras
// ---------------------------------------------------------------------
function Compras({ onNavigate, currentUser }) {
  const [aba, setAba] = React.useState(() => localStorage.getItem('ef_compras_aba') || 'ocs');
  const [ocs, setOcs] = React.useState([]);
  const [fornecedores, setFornecedores] = React.useState([]);
  const [events, setEvents] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [abertaId, setAbertaId] = React.useState(null);
  const [novaModal, setNovaModal] = React.useState(false);
  // Id da OC em correcao. Guardamos so o id, como em abertaId, para o
  // formulario reabrir sempre com a versao mais nova da lista.
  const [editandoId, setEditandoId] = React.useState(null);
  const [filtro, setFiltro] = React.useState('todos');
  // Quando a pessoa chega pelo botão "Compras do evento" na Agenda,
  // a busca já vem preenchida com o nome do evento.
  const [busca, setBusca] = React.useState(() => {
    const vindoDoEvento = localStorage.getItem('ef_compras_evento');
    if (vindoDoEvento) localStorage.removeItem('ef_compras_evento');
    return vindoDoEvento || '';
  });
  const [busy, setBusy] = React.useState(null);
  const [cancelConfirm, setCancelConfirm] = React.useState(null);
  const [toast, setToast] = React.useState(null);
  const showToast = (msg, type = 'success') => { setToast({ msg, type }); setTimeout(() => setToast(null), 4500); };
  const pdfRef = React.useRef(null);

  const trocarAba = (id) => { setAba(id); localStorage.setItem('ef_compras_aba', id); };

  const carregar = React.useCallback(async () => {
    const [{ data: o }, { data: f }, { data: e }] = await Promise.all([
      sb.from('purchase_orders').select('*').order('created_at', { ascending: false }),
      sb.from('fornecedores').select('*').order('nome'),
      sb.from('events').select('id, name, event_date, client_name, location').order('event_date', { ascending: false }).limit(200),
    ]);
    setOcs(o || []); setFornecedores(f || []); setEvents(e || []);
    setLoading(false);
  }, []);

  React.useEffect(() => { carregar(); }, [carregar]);

  // Guardamos só o id: o detalhe sempre lê a versão mais nova da lista.
  const aberta = ocs.find(o => o.id === abertaId) || null;
  const editando = ocs.find(o => o.id === editandoId) || null;

  // Conteúdo da OC — o mesmo na criação e na correção. Os campos de snapshot
  // são recopiados do cadastro atual do fornecedor e do evento: se a pessoa
  // trocou o fornecedor errado pelo certo, os dados bancários têm que vir junto.
  const conteudoOC = ({ fornecedor, evento, descricao, itens, data_servico, forma_pagamento, prazo_pagamento, observacoes }) => ({
    fornecedor_id: fornecedor.id,
    fornecedor_nome: fornecedor.nome,
    fornecedor_contato: fornecedor.contato || null,
    fornecedor_email: fornecedor.email || null,
    fornecedor_telefone: fornecedor.telefone || null,
    dados_bancarios: {
      banco: fornecedor.banco || '', agencia: fornecedor.agencia || '', conta: fornecedor.conta || '',
      tipo_conta: fornecedor.tipo_conta || '', pix_tipo: fornecedor.pix_tipo || '', pix_chave: fornecedor.pix_chave || '',
      favorecido: fornecedor.favorecido || fornecedor.nome, favorecido_doc: fornecedor.favorecido_doc || '',
    },
    event_id: evento ? evento.id : null,
    evento_nome: evento ? evento.name : null,
    evento_data: evento ? evento.event_date : null,
    evento_local: evento ? evento.location : null,
    cliente_nome: evento ? evento.client_name : null,
    descricao: descricao || null,
    itens: itens || [],
    valor_total: somaItens(itens),
    data_servico: data_servico || null,
    forma_pagamento: forma_pagamento || 'PIX',
    prazo_pagamento: prazo_pagamento || null,
    observacoes: observacoes || null,
  });

  // ---- criação da OC (usada pelo modal e pela aba de Cotações) ----
  const criarOC = async ({ fornecedor, evento, descricao, itens, data_servico, forma_pagamento, prazo_pagamento, observacoes, quote_request_supplier_id = null }) => {
    const payload = {
      ...conteudoOC({ fornecedor, evento, descricao, itens, data_servico, forma_pagamento, prazo_pagamento, observacoes }),
      status: 'Rascunho',
      created_by: currentUser?.id || null,
      quote_request_supplier_id,
    };
    const { data, error } = await sb.from('purchase_orders').insert(payload).select().single();
    if (error) { console.error('[Compras.criarOC] erro:', error); return null; }
    setOcs(prev => [data, ...prev]);
    return data;
  };

  // Chamado pela aba de Cotações quando a equipe escolhe o vencedor
  const gerarOCdaCotacao = async ({ pedido, linha, fornecedor }) => {
    const evento = events.find(e => e.id === pedido.event_id) || null;
    const oc = await criarOC({
      fornecedor,
      evento,
      descricao: [pedido.titulo, pedido.descricao].filter(Boolean).join('\n\n'),
      itens: [{ descricao: pedido.titulo, qtd: 1, unidade: 'serviço', valor_unit: Number(linha.valor) || 0 }],
      data_servico: pedido.evento_data || null,
      forma_pagamento: 'PIX',
      // prazo_pagamento fica em branco de propósito: o fornecedor informa
      // prazo de ENTREGA na cotação, que é outra coisa. Quem define quando
      // paga é a Promoup — a pessoa preenche antes de enviar a OC.
      prazo_pagamento: null,
      observacoes: [
        linha.prazo_entrega ? `Prazo informado pelo fornecedor na cotação: ${linha.prazo_entrega}` : '',
        linha.observacoes || '',
      ].filter(Boolean).join('\n') || null,
      quote_request_supplier_id: linha.id,
    });
    if (oc) { trocarAba('ocs'); setAbertaId(oc.id); }
    return oc;
  };

  // ---- ações sobre uma OC ----
  const atualizar = async (id, patch) => {
    const { data, error } = await sb.from('purchase_orders').update(patch).eq('id', id).select().single();
    if (error) { console.error('[Compras.atualizar] erro:', error); return null; }
    setOcs(prev => prev.map(o => o.id === data.id ? data : o));
    return data;
  };

  // ---- correção de uma OC já criada ----
  // Número, token, status e a conta a pagar não são tocados: o documento
  // continua sendo o mesmo, só com o conteúdo certo. O pdf_url é zerado
  // porque o arquivo que está no Storage virou a versão velha.
  const editarOC = async (oc, dados) => {
    if (!OC_EDITAVEL.includes(oc.status)) {
      showToast(`${oc.numero} está ${oc.status} e não pode mais ser corrigida.`, 'danger');
      return null;
    }
    const atualizada = await atualizar(oc.id, {
      ...conteudoOC(dados),
      pdf_url: null,
      updated_at: new Date().toISOString(),
    });
    if (!atualizada) { showToast('Não consegui salvar a correção.', 'danger'); return null; }
    setEditandoId(null);
    setAbertaId(atualizada.id);
    showToast(
      atualizada.status === 'Enviada'
        ? `${atualizada.numero} corrigida. Reenvie ao fornecedor para ele receber o PDF novo.`
        : `${atualizada.numero} corrigida.`
    );
    return atualizada;
  };

  // Dá tempo do template invisível renderizar com a OC certa antes de capturar
  const esperarTemplate = () => new Promise(r => setTimeout(r, 150));

  const baixarPDF = async (oc) => {
    setBusy('pdf'); await esperarTemplate();
    await renderPDF(pdfRef.current, `${oc.numero}_${(oc.fornecedor_nome || '').replace(/[^\w]/g, '_')}.pdf`);
    setBusy(null);
  };

  const enviarWhatsApp = async (oc) => {
    const forn = fornecedores.find(f => f.id === oc.fornecedor_id);
    if (!forn?.telefone) { showToast('Fornecedor sem telefone cadastrado. Use o e-mail ou copie o link.', 'danger'); return; }
    setBusy('wpp');
    await esperarTemplate();

    // Sobe o PDF: a Z-API só entrega documento por URL pública
    const blob = await ocPdfBlob(pdfRef.current);
    const pdfUrl = blob ? await uploadDocPdf(blob, `${oc.numero}.pdf`) : null;

    const r = await notifyFornecedorWhatsApp({
      fornecedor: forn,
      text: mensagemOC({ oc, link: publicDocUrl(oc.token) }),
      mediaUrl: pdfUrl,
      mediaFilename: `${oc.numero}.pdf`,
    });

    if (r.ok) {
      await atualizar(oc.id, {
        status: oc.status === 'Rascunho' ? 'Enviada' : oc.status,
        sent_at: new Date().toISOString(), sent_via: 'whatsapp',
        pdf_url: pdfUrl || oc.pdf_url,
      });
    }
    setBusy(null);
    showToast(
      r.ok && !pdfUrl ? 'Mensagem enviada, mas o PDF não subiu — o fornecedor recebeu o link.' : r.motivo,
      r.ok ? 'success' : 'danger'
    );
  };

  const enviarEmail = async (oc) => {
    if (!oc.fornecedor_email) { showToast('Fornecedor sem e-mail cadastrado.', 'danger'); return; }
    setBusy('email'); await esperarTemplate();
    // Baixa o PDF para a pessoa anexar: o sistema não tem servidor de e-mail
    await renderPDF(pdfRef.current, `${oc.numero}.pdf`);
    abrirEmail({
      to: oc.fornecedor_email,
      subject: `Ordem de Compra ${oc.numero} — Promoup`,
      body: mensagemOC({ oc, link: publicDocUrl(oc.token) })
        + '\n\n(O PDF da OC foi baixado no seu computador — anexe nesta mensagem antes de enviar.)',
    });
    await atualizar(oc.id, {
      status: oc.status === 'Rascunho' ? 'Enviada' : oc.status,
      sent_at: new Date().toISOString(), sent_via: 'email',
    });
    setBusy(null);
    showToast('E-mail aberto. Anexe o PDF que acabou de baixar e envie.');
  };

  const marcarEnviada = async (oc) => {
    await atualizar(oc.id, { status: 'Enviada', sent_at: new Date().toISOString(), sent_via: 'manual' });
    showToast('OC marcada como enviada. O fornecedor já pode responder pelo link.');
  };

  const cancelar = async (oc) => {
    await atualizar(oc.id, { status: 'Cancelada' });
    setCancelConfirm(null);
    showToast(`${oc.numero} cancelada. O link do fornecedor deixou de valer.`);
  };

  const copiarLink = (oc) => {
    navigator.clipboard?.writeText(publicDocUrl(oc.token));
    showToast('Link copiado. Cole no WhatsApp ou e-mail do fornecedor.');
  };

  // ---- lista filtrada ----
  const filtradas = ocs.filter(o => {
    if (filtro !== 'todos' && o.status !== filtro) return false;
    const q = busca.trim().toLowerCase();
    if (!q) return true;
    return [o.numero, o.fornecedor_nome, o.evento_nome, o.cliente_nome, o.descricao]
      .some(v => (v || '').toLowerCase().includes(q));
  });

  const totais = {
    abertas: ocs.filter(o => o.status === 'Enviada').length,
    confirmadas: ocs.filter(o => o.status === 'Confirmada').length,
    valorConfirmado: ocs.filter(o => o.status === 'Confirmada').reduce((s, o) => s + (Number(o.valor_total) || 0), 0),
  };

  const ABAS = [{ id: 'ocs', label: 'Ordens de Compra' }, { id: 'cotacoes', label: 'Cotações' }];

  return (
    <div>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 20, gap: 16, flexWrap: 'wrap' }}>
        <div>
          <h1 style={{ fontSize: 24, fontWeight: 700, color: DS.colors.text, margin: 0, letterSpacing: '-0.02em' }}>Compras</h1>
          <p style={{ fontSize: 13, color: DS.colors.textSec, margin: '4px 0 0' }}>
            Cotação com fornecedores, ordem de compra e conta a pagar — tudo registrado.
          </p>
        </div>
        {aba === 'ocs' && <Btn icon="plus" onClick={() => setNovaModal(true)}>Nova Ordem de Compra</Btn>}
      </div>

      {/* Abas */}
      <div style={{ display: 'flex', gap: 4, borderBottom: `1px solid ${DS.colors.border}`, marginBottom: 22 }}>
        {ABAS.map(t => (
          <button key={t.id} onClick={() => trocarAba(t.id)} style={{
            background: 'transparent', border: 'none', cursor: 'pointer', padding: '10px 16px',
            fontSize: 13, fontWeight: 700, fontFamily: 'inherit',
            color: aba === t.id ? DS.colors.primary : DS.colors.textMuted,
            borderBottom: `2px solid ${aba === t.id ? DS.colors.primary : 'transparent'}`, marginBottom: -1,
          }}>{t.label}</button>
        ))}
      </div>

      {aba === 'cotacoes' ? (
        <Cotacoes onGerarOC={gerarOCdaCotacao} />
      ) : loading ? <Spinner /> : (
        <>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 12, marginBottom: 20 }}>
            {[
              { label: 'Aguardando resposta', value: totais.abertas, color: DS.colors.primary },
              { label: 'Confirmadas', value: totais.confirmadas, color: DS.colors.success },
              { label: 'Valor confirmado', value: fmtBRL(totais.valorConfirmado), color: DS.colors.text },
            ].map(s => (
              <Card key={s.label} style={{ padding: '14px 18px' }}>
                <div style={{ fontSize: 11, color: DS.colors.textMuted, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.06em' }}>{s.label}</div>
                <div style={{ fontSize: 22, fontWeight: 800, color: s.color, marginTop: 4 }}>{s.value}</div>
              </Card>
            ))}
          </div>

          <div style={{ display: 'flex', gap: 8, marginBottom: 14, flexWrap: 'wrap' }}>
            <input value={busca} onChange={e => setBusca(e.target.value)} placeholder="Buscar por número, fornecedor, evento…"
              style={{ flex: 1, minWidth: 220, border: `1px solid ${DS.colors.border}`, borderRadius: DS.radius.sm, padding: '8px 12px', fontSize: 13, outline: 'none', fontFamily: 'inherit' }} />
            <Select value={filtro} onChange={setFiltro} style={{ minWidth: 170 }}
              options={[{ value: 'todos', label: 'Todos os status' },
                ...Object.keys(OC_STATUS_VARIANT).map(s => ({ value: s, label: s }))]} />
          </div>

          <Card>
            {filtradas.length === 0 ? (
              <EmptyState icon="briefcase" title="Nenhuma ordem de compra"
                desc="Crie uma OC direto ou escolha um fornecedor na aba Cotações." />
            ) : (
              <>
                <div style={{ display: 'grid', gridTemplateColumns: '1fr 1.6fr 1.6fr 1fr 1fr', padding: '10px 22px', borderBottom: `1px solid ${DS.colors.border}`, fontSize: 11, fontWeight: 700, color: DS.colors.textMuted, textTransform: 'uppercase', letterSpacing: '0.06em' }}>
                  <span>Número</span><span>Fornecedor</span><span>Evento</span><span style={{ textAlign: 'right' }}>Valor</span><span style={{ textAlign: 'right' }}>Status</span>
                </div>
                {filtradas.map((o, i) => (
                  <div key={o.id} onClick={() => setAbertaId(o.id)}
                    style={{ display: 'grid', gridTemplateColumns: '1fr 1.6fr 1.6fr 1fr 1fr', padding: '14px 22px', borderBottom: i < filtradas.length - 1 ? `1px solid ${DS.colors.border}` : 'none', alignItems: 'center', cursor: 'pointer' }}
                    onMouseEnter={e => e.currentTarget.style.background = '#F8FAFC'}
                    onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
                    <div>
                      <div style={{ fontSize: 13, fontWeight: 700, color: DS.colors.text }}>{o.numero}</div>
                      <div style={{ fontSize: 11, color: DS.colors.textMuted }}>{dataBR(o.created_at)}</div>
                    </div>
                    <div style={{ fontSize: 13, color: DS.colors.text, overflow: 'hidden', textOverflow: 'ellipsis', paddingRight: 8 }}>{o.fornecedor_nome}</div>
                    <div style={{ overflow: 'hidden', paddingRight: 8 }}>
                      <div style={{ fontSize: 13, color: DS.colors.text, textOverflow: 'ellipsis', overflow: 'hidden', whiteSpace: 'nowrap' }}>{o.evento_nome || '—'}</div>
                      <div style={{ fontSize: 11, color: DS.colors.textMuted }}>{o.cliente_nome || ''}</div>
                    </div>
                    <div style={{ fontSize: 14, fontWeight: 800, color: DS.colors.text, textAlign: 'right' }}>{fmtBRL(o.valor_total)}</div>
                    <div style={{ textAlign: 'right' }}><Badge variant={OC_STATUS_VARIANT[o.status]}>{o.status}</Badge></div>
                  </div>
                ))}
              </>
            )}
          </Card>
        </>
      )}

      {/* O detalhe some enquanto o formulário de correção está aberto: dois
          modais empilhados deixariam a tela confusa. Ao fechar a correção, o
          detalhe volta sozinho, já com os dados novos. */}
      <OCDetalhe
        oc={editando ? null : aberta}
        busy={busy}
        onClose={() => setAbertaId(null)}
        onEditar={(oc) => setEditandoId(oc.id)}
        onPDF={baixarPDF}
        onWhatsApp={enviarWhatsApp}
        onEmail={enviarEmail}
        onLink={copiarLink}
        onMarcarEnviada={marcarEnviada}
        onCancelar={(oc) => setCancelConfirm(oc)}
        onVerFinanceiro={() => onNavigate?.('financeiro')}
      />

      <Modal open={!!cancelConfirm} onClose={() => setCancelConfirm(null)} title="Cancelar ordem de compra" width={430}>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          <p style={{ fontSize: 14, color: DS.colors.textSec, lineHeight: 1.6 }}>
            Cancelar a <strong style={{ color: DS.colors.text }}>{cancelConfirm?.numero}</strong>? O link do fornecedor
            para de funcionar na hora. Se ele já tinha confirmado, a conta a pagar continua no Financeiro e
            precisa ser removida por lá.
          </p>
          <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
            <Btn variant="secondary" onClick={() => setCancelConfirm(null)}>Voltar</Btn>
            <Btn variant="danger" icon="x" onClick={() => cancelar(cancelConfirm)}>Cancelar OC</Btn>
          </div>
        </div>
      </Modal>

      {/* Mesmo formulário para criar e para corrigir — o que muda é receber
          ou não uma OC em `oc`. */}
      <OCFormModal
        open={novaModal || !!editando}
        oc={editando}
        fornecedores={fornecedores}
        events={events}
        onClose={() => { setNovaModal(false); setEditandoId(null); }}
        onSubmit={async (dados) => {
          if (editando) { await editarOC(editando, dados); return; }
          const oc = await criarOC(dados);
          if (!oc) { showToast('Não consegui criar a OC.', 'danger'); return; }
          setNovaModal(false);
          setAbertaId(oc.id);
          showToast(`${oc.numero} criada. Revise e envie ao fornecedor.`);
        }}
      />

      {/* Template invisível que vira PDF */}
      <OCPDFTemplate oc={aberta} innerRef={pdfRef} />

      {toast && <Toast message={toast.msg} type={toast.type} onClose={() => setToast(null)} />}
    </div>
  );
}

Object.assign(window, { Compras, OCPDFTemplate, mensagemOC, somaItens, OC_STATUS_VARIANT, FORMAS_PAGAMENTO, ocPdfBlob, dataBR });
