/* global React, Icon, Button, Badge, Card, Drawer, PageHead, Toolbar, KpiMini, brl, Field,
          NF_STATUS, NATUREZAS_OPERACAO, MODALIDADES_FRETE, REGIMES_TRIBUTARIOS, EMPRESA_CORES, BLANK_EMPRESA,
          formatCNPJ, formatChaveAcesso, NFStatusBadge, EmpresaBadge, NFKpiCards, NFTabs,
          EmpresaEmissoraForm, NFEmissaoDrawer */
// ─── NF Sections — Page sections for Nota Fiscal module ──────────────────

const { useState: useNfsState, useEffect: useNfsEffect, useCallback: useNfsCb, useRef: useNfsRef, useMemo: useNfsMemo } = React;

// ─── 1. NFEmissao ────────────────────────────────────────────────────────
function NFEmissao({ onNav }) {
  const [pedidos, setPedidos] = useNfsState([]);
  const [loading, setLoading] = useNfsState(true);
  const [empresas, setEmpresas] = useNfsState([]);
  const [drawer, setDrawer] = useNfsState(null); // { pedido, items, clienteData }
  const [saving, setSaving] = useNfsState(false);
  const [nfsHoje, setNfsHoje] = useNfsState(0);
  const [itensPorPedido, setItensPorPedido] = useNfsState({});

  // Load empresas emissoras
  useNfsEffect(() => {
    if (!window.tmSupabase) return;
    window.tmSupabase.from('empresas_emissoras').select('*').eq('ativo', true).order('nome_fantasia')
      .then(({ data }) => { if (data) setEmpresas(data); });
  }, []);

  // Load pedidos "Em andamento"
  const loadPedidos = useNfsCb(async () => {
    if (!window.tmSupabase) { setLoading(false); return; }
    setLoading(true);
    const { data } = await window.tmSupabase.from('pedidos').select('*')
      .eq('status', 'Em andamento').order('created_at', { ascending: false });
    if (data) setPedidos(data.map(r => window.fromDbPedido ? window.fromDbPedido(r) : r));

    // Count items per pedido
    const { data: allItems } = await window.tmSupabase.from('pedido_itens').select('pedido_id');
    if (allItems) {
      const map = {};
      allItems.forEach(r => { map[r.pedido_id] = (map[r.pedido_id] || 0) + 1; });
      setItensPorPedido(map);
    }

    // Count NFs emitidas hoje
    const today = new Date().toISOString().slice(0, 10);
    const { count } = await window.tmSupabase.from('notas_fiscais').select('id', { count: 'exact', head: true })
      .gte('created_at', today + 'T00:00:00');
    setNfsHoje(count || 0);

    setLoading(false);
  }, []);

  useNfsEffect(() => { loadPedidos(); }, [loadPedidos]);

  // Open emission drawer for a pedido
  const openEmissao = async (pedido) => {
    // 1. Load pedido items
    let items = [];
    if (window.tmDb && pedido.id) {
      items = await window.tmDb.loadPedidoItens(pedido.id);
    }

    // 2. Fetch client data (CPF/CNPJ, email, phone) from clientes/saloes/distribuidores
    let clienteData = null;
    if (pedido.cli && window.tmSupabase) {
      const nome = pedido.cli;
      // Each table has different columns — select all available contact/address fields
      const addrCols = ',geral_cidade,geral_uf,geral_cep,geral_bairro,geral_endereco,geral_numero,geral_complemento,inscricao_estadual';
      const [c, s, d] = await Promise.all([
        window.tmSupabase.from('clientes').select('nome,cpf,email,celular,whats,tipo_pessoa' + addrCols).eq('nome', nome).maybeSingle(),
        window.tmSupabase.from('saloes').select('nome,cnpj,cpf,email,celular,fone,tipo_pessoa' + addrCols).eq('nome', nome).maybeSingle(),
        window.tmSupabase.from('distribuidores').select('nome,cnpj,cpf,email,celular,fone,tipo_pessoa' + addrCols).eq('nome', nome).maybeSingle(),
      ]);
      clienteData = c.data || s.data || d.data || null;
    }

    setDrawer({ pedido, items, clienteData });
  };

  // Handle emission — calls Edge Function nfe-proxy → NFe.io (or simulated)
  const handleEmitir = async (nfData) => {
    if (!window.tmSupabase) return;
    setSaving(true);
    try {
      // 1. Increment numero NF on the empresa
      const { data: empData, error: empErr } = await window.tmSupabase
        .from('empresas_emissoras')
        .select('ultimo_numero_nfe, serie_nfe, nfeio_company_id')
        .eq('id', nfData.empresaId).single();
      if (empErr) throw empErr;

      const novoNumero = (empData.ultimo_numero_nfe || 0) + 1;

      await window.tmSupabase.from('empresas_emissoras')
        .update({ ultimo_numero_nfe: novoNumero, updated_at: new Date().toISOString() })
        .eq('id', nfData.empresaId);

      // 2. Call Edge Function to emit via NFe.io (or simulated)
      let nfeResult = null;
      if (window.nfeApi) {
        nfeResult = await window.nfeApi.emitir(empData.nfeio_company_id || nfData.empresaId, nfData);
      }

      const isRejected = nfeResult && nfeResult.error;
      const isIssued = nfeResult && (nfeResult.status === 'Issued' || nfeResult.status === 'Autorizada');
      const nfStatus = isRejected ? 'Rejeitada' : isIssued ? 'Autorizada' : 'Processando';

      // 3. Create nota_fiscal record
      const nfRecord = {
        empresa_emissora_id: nfData.empresaId,
        pedido_id: drawer.pedido.id,
        numero: novoNumero,
        serie: empData.serie_nfe || 1,
        natureza_operacao: nfData.natureza,
        tipo_operacao: nfData.tipoSaida || 'saida',
        dest_nome: nfData.destNome,
        dest_doc: nfData.destDoc,
        dest_ie: nfData.destIe || null,
        ind_ie_dest: nfData.indIEDest || '1',
        dest_endereco: nfData.destEndereco || {},
        dest_email: nfData.destEmail || null,
        valor_produtos: nfData.valorProdutos,
        valor_frete: nfData.valorFrete || 0,
        valor_desconto: nfData.valorDesconto || 0,
        valor_outras: nfData.valorOutras || 0,
        valor_total: nfData.valorTotal,
        icms_base: nfData.icmsBase || 0,
        icms_valor: nfData.icmsValor || 0,
        modalidade_frete: nfData.modalidadeFrete,
        transportador: nfData.transportador || {},
        volumes: nfData.volumes ? [nfData.volumes] : [],
        forma_pagamento: nfData.formaPagamento,
        parcelas: nfData.parcelas,
        info_complementar: nfData.infoComplementar || null,
        obs_internas: nfData.obsInternas || null,
        status: nfStatus,
        data_emissao: new Date().toISOString(),
        data_autorizacao: isIssued ? new Date().toISOString() : null,
        // NFe.io fields
        nfeio_id: nfeResult?.id || null,
        chave_acesso: nfeResult?.authorization?.accessKey || null,
        protocolo: nfeResult?.authorization?.protocol || null,
        xml_url: nfeResult?.xml?.uri || null,
        danfe_url: nfeResult?.pdf?.uri || null,
        motivo_rejeicao: isRejected
          ? (nfeResult.message && nfeResult.message !== 'Erro NFe.io'
              ? nfeResult.message
              : nfeResult.details?.Message || nfeResult.details?.message
                || (nfeResult.details?.errors ? JSON.stringify(nfeResult.details.errors)
                : nfeResult.httpStatus ? `HTTP ${nfeResult.httpStatus}` : 'Erro desconhecido'))
          : null,
      };

      const { data: nfInserted, error: nfErr } = await window.tmSupabase
        .from('notas_fiscais').insert(nfRecord).select().single();
      if (nfErr) throw nfErr;

      // 4. Create NF items
      const nfItems = nfData.items.map((it, i) => ({
        nota_fiscal_id: nfInserted.id,
        produto_id: it.produtoId || null,
        numero_item: i + 1,
        sku: it.sku || null,
        descricao: it.desc || 'Item',
        ncm: it.ncm || '3305.10.00',
        unidade: it.un || 'UN',
        quantidade: parseFloat(it.qty) || 0,
        valor_unitario: it.valorUnitario || 0,
        valor_total: it.valorTotal || 0,
        desconto: 0,
      }));

      if (nfItems.length > 0) {
        await window.tmSupabase.from('notas_fiscais_itens').insert(nfItems);
      }

      // 5. If not rejected: update pedido + create contas_receber
      if (!isRejected) {
        await window.tmSupabase.from('pedidos')
          .update({ status: 'Atendido', nota_fiscal_id: nfInserted.id, empresa_emissora_id: nfData.empresaId })
          .eq('id', drawer.pedido.id);

        const parcelas = drawer.pedido.parcelas || [];
        if (parcelas.length > 0) {
          const toIso = (br) => {
            const m = String(br || '').match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
            return m ? `${m[3]}-${m[2]}-${m[1]}` : null;
          };
          const rows = parcelas.map((par, i) => ({
            referencia: `${drawer.pedido.num}/${i + 1}`,
            cliente_nome: drawer.pedido.cli,
            pedido_ref: drawer.pedido.num,
            pedido_id: drawer.pedido.id,
            vencimento: toIso(par.venc),
            parcela: i + 1,
            valor: typeof par.valor === 'number' ? par.valor : parseFloat(par.valor) || 0,
            valor_recebido: 0,
            status: 'Em aberto',
            forma_pagamento: par.forma || 'Dinheiro',
            conta_bancaria: par.conta || null,
          }));
          await window.tmSupabase.from('contas_receber').insert(rows);
        }
      }

      // 6. Create log
      const logMsg = isRejected
        ? `NF-e nº ${novoNumero} REJEITADA: ${nfeResult.message || 'erro desconhecido'}`
        : `NF-e nº ${novoNumero} emitida com sucesso para ${nfData.destNome}${nfeResult?.simulated ? ' (modo simulado)' : ''}`;

      await window.tmSupabase.from('nf_logs').insert({
        nota_fiscal_id: nfInserted.id,
        tipo: isRejected ? 'error' : 'info',
        mensagem: logMsg,
        detalhes: isRejected ? {
          empresa: nfData.empresa?.nome_fantasia,
          valor: nfData.valorTotal,
          simulated: nfeResult?.simulated || false,
          httpStatus: nfeResult?.httpStatus || null,
          nfeMessage: nfeResult?.message || null,
          nfeDetails: nfeResult?.details || null,
        } : {
          empresa: nfData.empresa?.nome_fantasia,
          valor: nfData.valorTotal,
          nfeio_id: nfeResult?.id,
          simulated: nfeResult?.simulated || false,
          chave_acesso: nfeResult?.authorization?.accessKey,
        },
      });

      setDrawer(null);
      loadPedidos();
      onNav('nf/historico');

    } catch (e) {
      alert('Erro ao emitir NF-e: ' + (e.message || String(e)));
    } finally {
      setSaving(false);
    }
  };

  // Calculate KPIs
  const valorPendente = pedidos.reduce((s, p) => s + (parseFloat(p.total) || 0), 0);

  return (
    <div className="canvas">
      <PageHead title="Emitir Nota Fiscal" sub="Selecione um pedido para emissão de NF-e"
        right={<Button variant="secondary" icon="file-text" size="sm" onClick={() => onNav('nf/historico')}>Ver histórico</Button>} />
      <NFTabs active="emissao" onNav={onNav} />

      <div className="grid-4" style={{ marginBottom: 16 }}>
        <KpiMini lbl="Pedidos em aberto" v={String(pedidos.length)} sub="aguardando emissão" />
        <KpiMini lbl="Empresas ativas" v={String(empresas.length)} sub="CNPJs cadastrados" />
        <KpiMini lbl="NFs emitidas hoje" v={String(nfsHoje)} sub={new Date().toLocaleDateString('pt-BR')} />
        <KpiMini lbl="Valor pendente" v={brl(valorPendente)} sub="total em aberto" />
      </div>

      <Card>
        <Toolbar search="Buscar pedido, cliente…" />
        {loading ? (
          <div style={{ padding: '48px 0', textAlign: 'center', color: 'var(--tm-fg-3)', fontSize: 13 }}>Carregando pedidos...</div>
        ) : pedidos.length === 0 ? (
          <div style={{ padding: '48px 0', textAlign: 'center', color: 'var(--tm-fg-3)' }}>
            <Icon name="check-circle" size={36} style={{ opacity: 0.3, marginBottom: 12 }} />
            <div style={{ fontSize: 14, marginBottom: 6 }}>Nenhum pedido aguardando emissão</div>
            <div style={{ fontSize: 12 }}>Todos os pedidos em andamento foram faturados</div>
          </div>
        ) : (
          <table className="tbl">
            <thead>
              <tr><th>Nº Pedido</th><th>Cliente</th><th>Itens</th><th className="num right">Total</th><th>Data</th><th>Status</th><th></th></tr>
            </thead>
            <tbody>
              {pedidos.map(p => (
                <tr key={p.id}>
                  <td><span className="ref-mono gold">{p.num}</span></td>
                  <td>{p.cli}</td>
                  <td className="muted">{itensPorPedido[p.id] || '—'}</td>
                  <td className="num right">{brl(p.total)}</td>
                  <td className="muted">{p.dataVenda || p.data}</td>
                  <td><Badge tone="info">Em andamento</Badge></td>
                  <td>
                    <Button variant="primary" size="sm" icon="send" onClick={() => openEmissao(p)}>
                      Emitir NF-e
                    </Button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </Card>

      {drawer && (
        <NFEmissaoDrawer
          open={!!drawer}
          pedido={drawer.pedido}
          items={drawer.items}
          empresas={empresas}
          clienteData={drawer.clienteData}
          onEmitir={handleEmitir}
          onCancel={() => setDrawer(null)}
          saving={saving}
        />
      )}
    </div>
  );
}

// ─── 2. NFHistorico ──────────────────────────────────────────────────────
function NFHistorico({ onNav }) {
  const [nfs, setNfs] = useNfsState([]);
  const [loading, setLoading] = useNfsState(true);
  const [searchQ, setSearchQ] = useNfsState('');
  const [expanded, setExpanded] = useNfsState(null); // expanded row id
  const [cancelModal, setCancelModal] = useNfsState(null); // { nfId, numero }
  const [cancelReason, setCancelReason] = useNfsState('');
  const [cancelling, setCancelling] = useNfsState(false);
  const [simulated, setSimulated] = useNfsState(false);
  const [statusFilter, setStatusFilter] = useNfsState('');
  const [reemitDrawer, setReemitDrawer] = useNfsState(null); // { nf, pedido, items, clienteData, empresas }
  const [reemitSaving, setReemitSaving] = useNfsState(false);
  const [empresas, setEmpresas] = useNfsState([]);

  // DANFE Preview state
  const [previewUrl, setPreviewUrl] = useNfsState(null);
  const [previewLoading, setPreviewLoading] = useNfsState(false);
  const [previewNf, setPreviewNf] = useNfsState(null);

  const loadNfs = useNfsCb(async () => {
    if (!window.tmSupabase) { setLoading(false); return; }
    setLoading(true);
    const { data } = await window.tmSupabase
      .from('notas_fiscais')
      .select('*, empresas_emissoras(nome_fantasia, cor, cnpj)')
      .order('created_at', { ascending: false });
    if (data) setNfs(data);
    setLoading(false);
  }, []);

  useNfsEffect(() => { loadNfs(); }, [loadNfs]);

  // Load empresas emissoras (needed for reemit drawer)
  useNfsEffect(() => {
    if (!window.tmSupabase) return;
    window.tmSupabase.from('empresas_emissoras').select('*').eq('ativo', true).order('nome_fantasia')
      .then(({ data }) => { if (data) setEmpresas(data); });
  }, []);

  // Check if running in simulated mode
  useNfsEffect(() => {
    if (window.nfeApi) {
      window.nfeApi.checkConfig()
        .then(r => setSimulated(r?.mode === 'simulated' || r?.mode === 'simulado' || r?.configured === false))
        .catch(() => setSimulated(true));
    }
  }, []);

  const filtered = nfs.filter(n => {
    if (statusFilter && n.status !== statusFilter) return false;
    if (!searchQ) return true;
    const q = searchQ.toLowerCase();
    return (n.dest_nome || '').toLowerCase().includes(q)
      || String(n.numero).includes(q)
      || (n.chave_acesso || '').includes(q);
  });

  const fmtDate = (iso) => {
    if (!iso) return '—';
    return new Date(iso).toLocaleDateString('pt-BR', { day: '2-digit', month: '2-digit', year: '2-digit', hour: '2-digit', minute: '2-digit' });
  };

  const autorizadas = nfs.filter(n => n.status === 'Autorizada');
  const rejeitadas = nfs.filter(n => n.status === 'Rejeitada');
  const valorTotal = autorizadas.reduce((s, n) => s + (parseFloat(n.valor_total) || 0), 0);

  // Helper: get NFe.io company ID for an NF
  const getNfeioCompanyId = async (nf) => {
    if (!nf.empresa_emissora_id || !window.tmSupabase) return null;
    const { data: emp } = await window.tmSupabase.from('empresas_emissoras')
      .select('nfeio_company_id').eq('id', nf.empresa_emissora_id).single();
    return emp?.nfeio_company_id || null;
  };

  // Preview DANFE in modal
  const handlePreviewDanfe = async (nf) => {
    if (!nf.nfeio_id) { alert('Esta NF-e não possui ID do NFe.io para visualização.'); return; }
    setPreviewLoading(true);
    setPreviewNf(nf);
    try {
      const companyId = await getNfeioCompanyId(nf);
      if (!companyId) { alert('Empresa sem NFe.io Company ID configurado.'); setPreviewLoading(false); setPreviewNf(null); return; }
      if (window.nfeApi && window.nfeApi.previewDanfe) {
        const url = await window.nfeApi.previewDanfe(companyId, nf.nfeio_id);
        setPreviewUrl(url);
      }
    } catch (err) {
      alert('Erro ao carregar DANFE: ' + (err.message || err));
      setPreviewNf(null);
    } finally {
      setPreviewLoading(false);
    }
  };

  const closePreview = () => {
    if (previewUrl) { URL.revokeObjectURL(previewUrl); }
    setPreviewUrl(null);
    setPreviewNf(null);
  };

  // Download XML (authenticated)
  const handleDownloadXml = async (nf) => {
    if (!nf.nfeio_id) { alert('Esta NF-e não possui ID do NFe.io para download.'); return; }
    try {
      const companyId = await getNfeioCompanyId(nf);
      if (!companyId) { alert('Empresa sem NFe.io Company ID configurado.'); return; }
      if (window.nfeApi && window.nfeApi.downloadXml) {
        await window.nfeApi.downloadXml(companyId, nf.nfeio_id, 'nfe-' + (nf.numero || '') + '.xml');
      } else if (nf.xml_url) {
        window.open(nf.xml_url, '_blank');
      }
    } catch (err) {
      alert('Erro ao baixar XML: ' + (err.message || err));
    }
  };

  // Download / Print DANFE (authenticated)
  const handleDownloadDanfe = async (nf, print) => {
    if (!nf.nfeio_id) { alert('Esta NF-e não possui ID do NFe.io para download.'); return; }
    try {
      const companyId = await getNfeioCompanyId(nf);
      if (!companyId) { alert('Empresa sem NFe.io Company ID configurado.'); return; }
      if (window.nfeApi && window.nfeApi.downloadDanfe) {
        await window.nfeApi.downloadDanfe(companyId, nf.nfeio_id, 'danfe-' + (nf.numero || '') + '.pdf', print);
      } else if (nf.danfe_url) {
        window.open(nf.danfe_url, '_blank');
      }
    } catch (err) {
      alert('Erro ao baixar DANFE: ' + (err.message || err));
    }
  };

  // Cancel NF-e
  const handleCancel = async () => {
    if (!cancelModal || !cancelReason.trim()) { alert('Informe o motivo do cancelamento (obrigatório pela SEFAZ).'); return; }
    setCancelling(true);
    try {
      const nf = nfs.find(n => n.id === cancelModal.nfId);
      if (!nf) throw new Error('NF não encontrada');

      // Call Edge Function to cancel at NFe.io
      if (window.nfeApi && nf.nfeio_id && nf.empresa_emissora_id) {
        // Get nfeio_company_id for this empresa
        const { data: emp } = await window.tmSupabase.from('empresas_emissoras')
          .select('nfeio_company_id').eq('id', nf.empresa_emissora_id).single();
        if (emp?.nfeio_company_id) {
          await window.nfeApi.cancelar(emp.nfeio_company_id, nf.nfeio_id, cancelReason.trim());
        }
      }

      // Update status in DB
      await window.tmSupabase.from('notas_fiscais').update({
        status: 'Cancelada',
        updated_at: new Date().toISOString(),
      }).eq('id', cancelModal.nfId);

      // Create log
      await window.tmSupabase.from('nf_logs').insert({
        nota_fiscal_id: cancelModal.nfId,
        tipo: 'warning',
        mensagem: `NF-e ${cancelModal.numero} cancelada. Motivo: ${cancelReason.trim()}`,
        detalhes: { motivo: cancelReason.trim() },
      });

      setCancelModal(null);
      setCancelReason('');
      loadNfs();
    } catch (e) {
      alert('Erro ao cancelar: ' + (e.message || String(e)));
    } finally {
      setCancelling(false);
    }
  };

  // Check NFe.io status and update NF record (for Processando NFs or NFs missing chave_acesso)
  const [checking, setChecking] = useNfsState(null); // nf.id being checked
  const handleCheckStatus = async (nf) => {
    if (!window.nfeApi || !window.tmSupabase || !nf.nfeio_id) return;
    setChecking(nf.id);
    try {
      // Get empresa's nfeio_company_id
      const { data: emp } = await window.tmSupabase.from('empresas_emissoras')
        .select('nfeio_company_id').eq('id', nf.empresa_emissora_id).single();
      if (!emp?.nfeio_company_id) { alert('Empresa sem NFe.io Company ID configurado.'); return; }

      const result = await window.nfeApi.consultarStatus(emp.nfeio_company_id, nf.nfeio_id);
      const invoice = result?.data || result;

      // Map NFe.io status
      const statusMap = { Issued: 'Autorizada', Error: 'Rejeitada', Cancelled: 'Cancelada', Processing: 'Processando', Created: 'Processando', WaitingCalculateTaxes: 'Processando', WaitingSefazReceipt: 'Processando', WaitingSefazAuthorization: 'Processando' };
      const newStatus = statusMap[invoice.status] || nf.status;

      const updates = { status: newStatus, updated_at: new Date().toISOString() };
      if (invoice.authorization?.accessKey) updates.chave_acesso = invoice.authorization.accessKey;
      if (invoice.authorization?.protocol) updates.protocolo = String(invoice.authorization.protocol);
      if (newStatus === 'Autorizada' && !nf.data_autorizacao) updates.data_autorizacao = new Date().toISOString();
      if (invoice.xml?.uri) updates.xml_url = invoice.xml.uri;
      if (invoice.pdf?.uri) updates.danfe_url = invoice.pdf.uri;
      if (newStatus === 'Rejeitada') {
        // Extract best error message from NFe.io lastEvents
        const errParts = [];
        const events = invoice.lastEvents?.events || (Array.isArray(invoice.lastEvents) ? invoice.lastEvents : []);
        // Find the AuthorizationWithFailed event (or any error event)
        const failedEvt = events.find(e => e.type === 'AuthorizationWithFailed' || e.type === 'Error');
        if (failedEvt?.data?.message) {
          errParts.push(failedEvt.data.message);
          if (failedEvt.data.statusCode) errParts.push(`Código: ${failedEvt.data.statusCode}`);
        }
        if (invoice.flowMessage) errParts.push(invoice.flowMessage);
        updates.motivo_rejeicao = errParts.length > 0 ? errParts.join(' — ') : `Erro SEFAZ (status: ${invoice.status})`;
      }

      await window.tmSupabase.from('notas_fiscais').update(updates).eq('id', nf.id);

      // Create log (include raw invoice fields for debugging)
      const logDetalhes = {
        statusAnterior: nf.status,
        statusNovo: newStatus,
        nfeioStatus: invoice.status,
        chaveAcesso: updates.chave_acesso || null,
        flowStatus: invoice.flowStatus || null,
        flowMessage: invoice.flowMessage || null,
        environment: invoice.environment || null,
      };
      // Include extra fields for debugging
      if (newStatus === 'Rejeitada') {
        logDetalhes.lastEvents = invoice.lastEvents || null;
        logDetalhes.environmentType = invoice.environmentType || null;
      }
      await window.tmSupabase.from('nf_logs').insert({
        nota_fiscal_id: nf.id,
        tipo: newStatus === 'Rejeitada' ? 'error' : 'info',
        mensagem: `Status NF-e ${nf.numero}/${nf.serie} atualizado: ${newStatus}` + (updates.chave_acesso ? ` (chave: ...${updates.chave_acesso.slice(-8)})` : ''),
        detalhes: logDetalhes,
      });

      loadNfs();
    } catch (e) {
      alert('Erro ao consultar status: ' + (e.message || String(e)));
    } finally {
      setChecking(null);
    }
  };

  const toggleExpand = (id) => setExpanded(prev => prev === id ? null : id);

  // ── Open reemit drawer for rejected NF ──
  const handleOpenReemit = async (nf) => {
    if (!window.tmSupabase) return;

    // Load pedido data
    let pedido = null, items = [], clienteData = null;
    if (nf.pedido_id) {
      const { data: pedData } = await window.tmSupabase.from('pedidos').select('*').eq('id', nf.pedido_id).single();
      if (pedData) pedido = window.fromDbPedido ? window.fromDbPedido(pedData) : pedData;

      // Load pedido items
      if (window.tmDb) items = await window.tmDb.loadPedidoItens(nf.pedido_id);

      // Load client data
      const nome = nf.dest_nome || (pedido && pedido.cli);
      if (nome) {
        const addrCols = ',geral_cidade,geral_uf,geral_cep,geral_bairro,geral_endereco,geral_numero,geral_complemento,inscricao_estadual';
        const [c, s, d] = await Promise.all([
          window.tmSupabase.from('clientes').select('nome,cpf,email,celular,whats,tipo_pessoa' + addrCols).eq('nome', nome).maybeSingle(),
          window.tmSupabase.from('saloes').select('nome,cnpj,cpf,email,celular,fone,tipo_pessoa' + addrCols).eq('nome', nome).maybeSingle(),
          window.tmSupabase.from('distribuidores').select('nome,cnpj,cpf,email,celular,fone,tipo_pessoa' + addrCols).eq('nome', nome).maybeSingle(),
        ]);
        clienteData = c.data || s.data || d.data || null;
      }
    }

    // Build a pedido-like object with NF data so drawer auto-fills from NF record
    const nfAsPedido = {
      ...(pedido || {}),
      id: nf.pedido_id,
      cli: nf.dest_nome,
      cliId: nf.dest_doc,
      condPag: nf.forma_pagamento,
      obs: nf.info_complementar,
      obsInternas: nf.obs_internas,
      transp: nf.transportador || {},
      parcelas: nf.parcelas || [],
      pgto: nf.forma_pagamento,
      descontoExtra: nf.valor_desconto,
      outrasDespesas: nf.valor_outras,
      frete: nf.valor_frete,
    };

    setReemitDrawer({ nf, pedido: nfAsPedido, items, clienteData });
  };

  // ── Handle reemit submission — updates existing NF record ──
  const handleReemitSubmit = async (nfData) => {
    if (!window.tmSupabase || !reemitDrawer) return;
    setReemitSaving(true);
    try {
      const nf = reemitDrawer.nf;

      // Get empresa data
      const { data: empData, error: empErr } = await window.tmSupabase
        .from('empresas_emissoras')
        .select('ultimo_numero_nfe, serie_nfe, nfeio_company_id')
        .eq('id', nfData.empresaId).single();
      if (empErr) throw empErr;

      // Call Edge Function to emit via NFe.io
      let nfeResult = null;
      if (window.nfeApi) {
        nfeResult = await window.nfeApi.emitir(empData.nfeio_company_id || nfData.empresaId, nfData);
      }

      const isRejected = nfeResult && nfeResult.error;
      const isIssued = nfeResult && (nfeResult.status === 'Issued' || nfeResult.status === 'Autorizada');
      const nfStatus = isRejected ? 'Rejeitada' : isIssued ? 'Autorizada' : 'Processando';

      // Update existing NF record
      const updates = {
        empresa_emissora_id: nfData.empresaId,
        natureza_operacao: nfData.natureza,
        dest_nome: nfData.destNome,
        dest_doc: nfData.destDoc,
        dest_ie: nfData.destIe || null,
        ind_ie_dest: nfData.indIEDest || '1',
        dest_endereco: nfData.destEndereco || {},
        dest_email: nfData.destEmail || null,
        valor_produtos: nfData.valorProdutos,
        valor_frete: nfData.valorFrete || 0,
        valor_desconto: nfData.valorDesconto || 0,
        valor_outras: nfData.valorOutras || 0,
        valor_total: nfData.valorTotal,
        modalidade_frete: nfData.modalidadeFrete,
        transportador: nfData.transportador || {},
        volumes: nfData.volumes ? [nfData.volumes] : [],
        forma_pagamento: nfData.formaPagamento,
        info_complementar: nfData.infoComplementar || null,
        obs_internas: nfData.obsInternas || null,
        status: nfStatus,
        data_emissao: new Date().toISOString(),
        data_autorizacao: isIssued ? new Date().toISOString() : null,
        nfeio_id: nfeResult?.id || nf.nfeio_id,
        chave_acesso: nfeResult?.authorization?.accessKey || null,
        protocolo: nfeResult?.authorization?.protocol ? String(nfeResult.authorization.protocol) : null,
        motivo_rejeicao: isRejected ? (nfeResult.message || 'Erro na emissão') : null,
        updated_at: new Date().toISOString(),
      };

      await window.tmSupabase.from('notas_fiscais').update(updates).eq('id', nf.id);

      // If authorized, update pedido status
      if (isIssued && nf.pedido_id) {
        await window.tmSupabase.from('pedidos').update({
          status: 'Atendido',
          nota_fiscal_id: nf.id,
          empresa_emissora_id: nfData.empresaId,
        }).eq('id', nf.pedido_id);
      }

      // Log
      await window.tmSupabase.from('nf_logs').insert({
        nota_fiscal_id: nf.id,
        tipo: isRejected ? 'error' : 'info',
        mensagem: `NF-e nº ${nf.numero} REEMITIDA: ${nfStatus}` + (isRejected ? `. ${nfeResult.message || ''}` : ''),
        detalhes: { nfeResult, nfData: { destNome: nfData.destNome, destDoc: nfData.destDoc, destIe: nfData.destIe, valorTotal: nfData.valorTotal } },
      });

      // Check status if still processing
      if (nfStatus === 'Processando' && nfeResult?.id) {
        setTimeout(async () => {
          const updatedNf = { ...nf, nfeio_id: nfeResult.id, empresa_emissora_id: nfData.empresaId };
          await handleCheckStatus(updatedNf);
        }, 5000);
      }

      setReemitDrawer(null);
      loadNfs();
    } catch (e) {
      alert('Erro ao reemitir: ' + (e.message || String(e)));
    } finally {
      setReemitSaving(false);
    }
  };

  return (
    <div className="canvas">
      <PageHead title="Histórico de NF-e"
        sub={nfs.length > 0 ? `${nfs.length} nota${nfs.length !== 1 ? 's' : ''} emitida${nfs.length !== 1 ? 's' : ''}` : 'Nenhuma NF-e emitida'}
        right={<Button variant="primary" icon="plus" size="sm" onClick={() => onNav('nf/emissao')}>Nova NF-e</Button>} />
      <NFTabs active="historico" onNav={onNav} />

      {simulated && (
        <div style={{ padding: '10px 16px', background: 'var(--tm-warning-bg, #fff8e1)', borderRadius: 8, marginBottom: 12, display: 'flex', alignItems: 'center', gap: 10, fontSize: 13, color: 'var(--tm-warning-fg, #8d6e14)' }}>
          <Icon name="alert-triangle" size={16} />
          <span><strong>Modo simulado</strong> — API NFe.io não configurada. As NFs emitidas são simuladas e não possuem validade fiscal.</span>
        </div>
      )}

      <div className="grid-4" style={{ marginBottom: 16 }}>
        <KpiMini lbl="Total emitidas" v={String(nfs.length)} sub="todas as notas" />
        <KpiMini lbl="Autorizadas" v={String(autorizadas.length)} sub={autorizadas.length > 0 ? 'aprovadas pela SEFAZ' : 'sem dados'} />
        <KpiMini lbl="Valor total" v={brl(valorTotal)} sub="notas autorizadas" />
        <KpiMini lbl="Rejeitadas" v={String(rejeitadas.length)} sub={rejeitadas.length > 0 ? 'verificar logs' : 'nenhuma'} />
      </div>

      <Card>
        <div style={{ padding: '12px 16px', borderBottom: '1px solid var(--tm-line-1)', display: 'flex', gap: 12, alignItems: 'center', flexWrap: 'wrap' }}>
          <input className="input" placeholder="Buscar por número, destinatário, chave…"
            value={searchQ} onChange={e => setSearchQ(e.target.value)}
            style={{ flex: 1, minWidth: 200, maxWidth: 400 }} />
          <select className="input" value={statusFilter} onChange={e => setStatusFilter(e.target.value)}
            style={{ width: 160, fontSize: 13 }}>
            <option value="">Todos os status</option>
            <option value="Rascunho">Rascunho</option>
            <option value="Processando">Processando</option>
            <option value="Autorizada">Autorizada</option>
            <option value="Rejeitada">Rejeitada</option>
            <option value="Cancelada">Cancelada</option>
          </select>
        </div>
        {loading ? (
          <div style={{ padding: '48px 0', textAlign: 'center', color: 'var(--tm-fg-3)', fontSize: 13 }}>Carregando...</div>
        ) : filtered.length === 0 ? (
          <div style={{ padding: '48px 0', textAlign: 'center', color: 'var(--tm-fg-3)' }}>
            <Icon name="file-text" size={36} style={{ opacity: 0.3, marginBottom: 12 }} />
            <div style={{ fontSize: 14, marginBottom: 6 }}>Nenhuma NF-e encontrada</div>
            <div style={{ fontSize: 12 }}>As notas emitidas aparecerão aqui</div>
          </div>
        ) : (
          <table className="tbl">
            <thead>
              <tr><th style={{ width: 28 }}></th><th>Número</th><th>Empresa</th><th>Destinatário</th><th className="num right">Valor</th><th>Emitida em</th><th>Status</th><th></th></tr>
            </thead>
            <tbody>
              {filtered.map(n => (
                <React.Fragment key={n.id}>
                  <tr style={{ cursor: 'pointer' }} onClick={() => toggleExpand(n.id)}>
                    <td style={{ textAlign: 'center', color: 'var(--tm-fg-3)' }}>
                      <Icon name={expanded === n.id ? 'chevron-down' : 'chevron-right'} size={14} />
                    </td>
                    <td><span className="ref-mono gold">{n.numero}/{n.serie}</span></td>
                    <td><EmpresaBadge nome={n.empresas_emissoras?.nome_fantasia} cor={n.empresas_emissoras?.cor} /></td>
                    <td>{n.dest_nome || '—'}</td>
                    <td className="num right">{brl(n.valor_total)}</td>
                    <td className="muted">{fmtDate(n.data_emissao)}</td>
                    <td><NFStatusBadge status={n.status} /></td>
                    <td onClick={e => e.stopPropagation()}>
                      <div style={{ display: 'flex', gap: 6 }}>
                        {n.nfeio_id && (!n.chave_acesso || n.status === 'Processando') && (
                          <button className="icon-btn" title="Consultar status SEFAZ"
                            style={{ color: 'var(--tm-info, #5B8DEF)' }}
                            disabled={checking === n.id}
                            onClick={() => handleCheckStatus(n)}>
                            <Icon name={checking === n.id ? 'loader' : 'refresh-cw'} size={14} />
                          </button>
                        )}
                        {n.nfeio_id && (n.status === 'Autorizada' || n.status === 'Cancelada') && (
                          <>
                            <button className="icon-btn" title="Visualizar DANFE" onClick={() => handlePreviewDanfe(n)}><Icon name="eye" size={14} /></button>
                            <button className="icon-btn" title="Imprimir DANFE" onClick={() => handleDownloadDanfe(n, true)}><Icon name="printer" size={14} /></button>
                            <button className="icon-btn" title="Download DANFE" onClick={() => handleDownloadDanfe(n, false)}><Icon name="download" size={14} /></button>
                            <button className="icon-btn" title="Download XML" onClick={() => handleDownloadXml(n)}><Icon name="file-text" size={14} /></button>
                          </>
                        )}
                        {n.status === 'Rejeitada' && (
                          <button className="icon-btn" title="Editar e Reemitir"
                            style={{ color: 'var(--tm-warning, #D4A04A)' }}
                            onClick={() => handleOpenReemit(n)}>
                            <Icon name="edit" size={14} />
                          </button>
                        )}
                        {n.status === 'Autorizada' && (
                          <button className="icon-btn" title="Cancelar NF-e"
                            style={{ color: 'var(--tm-danger)' }}
                            onClick={() => { setCancelModal({ nfId: n.id, numero: `${n.numero}/${n.serie}` }); setCancelReason(''); }}>
                            <Icon name="x-circle" size={14} />
                          </button>
                        )}
                      </div>
                    </td>
                  </tr>
                  {expanded === n.id && (
                    <tr>
                      <td colSpan={8} style={{ background: 'var(--tm-bg-2)', padding: '12px 20px', borderBottom: '1px solid var(--tm-line-1)' }}>
                        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px 32px', fontSize: 12.5 }}>
                          <div>
                            <span className="muted">Chave de acesso:</span>{' '}
                            <span style={{ fontFamily: 'var(--tm-mono)', fontSize: 11.5, letterSpacing: '0.03em' }}>
                              {n.chave_acesso ? formatChaveAcesso(n.chave_acesso) : '—'}
                            </span>
                          </div>
                          <div>
                            <span className="muted">Protocolo:</span>{' '}
                            <span style={{ fontFamily: 'var(--tm-mono)' }}>{n.protocolo || '—'}</span>
                          </div>
                          <div>
                            <span className="muted">CNPJ emitente:</span>{' '}
                            {n.empresas_emissoras?.cnpj || '—'}
                          </div>
                          <div>
                            <span className="muted">Doc destinatário:</span>{' '}
                            {n.dest_doc || '—'}
                          </div>
                          <div>
                            <span className="muted">Natureza da operação:</span>{' '}
                            {n.natureza_operacao || '—'}
                          </div>
                          <div>
                            <span className="muted">Autorizada em:</span>{' '}
                            {fmtDate(n.data_autorizacao)}
                          </div>
                          {n.nfeio_id && (
                            <div>
                              <span className="muted">NFe.io ID:</span>{' '}
                              <span style={{ fontFamily: 'var(--tm-mono)', fontSize: 11 }}>{n.nfeio_id}</span>
                            </div>
                          )}
                          {n.motivo_rejeicao && (
                            <div style={{ gridColumn: '1 / -1', color: 'var(--tm-danger)' }}>
                              <span className="muted" style={{ color: 'var(--tm-danger)' }}>Motivo rejeição:</span>{' '}
                              {n.motivo_rejeicao}
                            </div>
                          )}
                          {n.nfeio_id && (!n.chave_acesso || n.status === 'Processando') && (
                            <div style={{ gridColumn: '1 / -1', paddingTop: 8 }}>
                              <Button variant="secondary" size="sm" icon={checking === n.id ? 'loader' : 'refresh-cw'}
                                disabled={checking === n.id}
                                onClick={() => handleCheckStatus(n)}>
                                {checking === n.id ? 'Consultando…' : 'Consultar Status SEFAZ'}
                              </Button>
                            </div>
                          )}
                          {n.status === 'Rejeitada' && (
                            <div style={{ gridColumn: '1 / -1', paddingTop: 8 }}>
                              <Button variant="primary" size="sm" icon="edit"
                                onClick={() => handleOpenReemit(n)}>
                                Editar e Reemitir
                              </Button>
                            </div>
                          )}
                          {/* Documents section — for authorized or any NF with nfeio_id */}
                          {n.nfeio_id && (n.status === 'Autorizada' || n.status === 'Cancelada') && (
                            <div style={{ gridColumn: '1 / -1', paddingTop: 12, borderTop: '1px solid var(--tm-line-1)', marginTop: 8 }}>
                              <div style={{ fontSize: 11, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.06em', color: 'var(--tm-fg-3)', marginBottom: 8 }}>Documentos</div>
                              <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap' }}>
                                <Button variant="primary" size="sm" icon="eye"
                                  onClick={() => handlePreviewDanfe(n)}>
                                  Visualizar DANFE
                                </Button>
                                <Button variant="secondary" size="sm" icon="printer"
                                  onClick={() => handleDownloadDanfe(n, true)}>
                                  Imprimir DANFE
                                </Button>
                                <Button variant="secondary" size="sm" icon="download"
                                  onClick={() => handleDownloadDanfe(n, false)}>
                                  Download DANFE
                                </Button>
                                <Button variant="secondary" size="sm" icon="file-text"
                                  onClick={() => handleDownloadXml(n)}>
                                  Download XML
                                </Button>
                                <Button variant="ghost" size="sm" icon="mail"
                                  onClick={() => {
                                    const email = n.dest_email || prompt('E-mail do destinatário:');
                                    if (email) {
                                      const danfeUrl = window.nfeApi ? window.nfeApi.getDanfeUrl(n.chave_acesso) : n.danfe_url;
                                      window.open('mailto:' + email + '?subject=NF-e ' + n.numero + '/' + n.serie + '&body=Segue a DANFE da NF-e ' + n.numero + '/' + n.serie + '. Acesse: ' + encodeURIComponent(danfeUrl || ''), '_blank');
                                    }
                                  }}>
                                  Enviar por E-mail
                                </Button>
                              </div>
                            </div>
                          )}
                          {n.info_complementar && (
                            <div style={{ gridColumn: '1 / -1' }}>
                              <span className="muted">Info complementar:</span>{' '}
                              {n.info_complementar}
                            </div>
                          )}
                        </div>
                      </td>
                    </tr>
                  )}
                </React.Fragment>
              ))}
            </tbody>
          </table>
        )}
      </Card>

      {/* DANFE Preview Modal */}
      {(previewNf) && (
        <div style={{ position: 'fixed', inset: 0, zIndex: 999, display: 'flex', flexDirection: 'column', alignItems: 'center', background: 'rgba(0,0,0,0.72)' }}
          onClick={(e) => { if (e.target === e.currentTarget) closePreview(); }}>
          {/* Toolbar */}
          <div style={{
            width: '100%', maxWidth: 900,
            display: 'flex', gap: 10, padding: '12px 20px',
            background: 'var(--tm-bg-1)', borderBottom: '1px solid var(--tm-line-1)',
            alignItems: 'center', flexShrink: 0,
          }}>
            <Icon name="file-text" size={16} style={{ color: 'var(--tm-brand-champagne)' }} />
            <span style={{ flex: 1, fontSize: 13.5, fontWeight: 600, color: 'var(--tm-fg-1)' }}>
              DANFE — NF-e {previewNf.numero}/{previewNf.serie}
              {previewNf.dest_nome ? ` · ${previewNf.dest_nome}` : ''}
            </span>
            {previewUrl && (
              <>
                <Button variant="secondary" size="sm" icon="printer" onClick={() => handleDownloadDanfe(previewNf, true)}>Imprimir</Button>
                <Button variant="secondary" size="sm" icon="download" onClick={() => handleDownloadDanfe(previewNf, false)}>Download</Button>
              </>
            )}
            <Button variant="ghost" size="sm" icon="x" onClick={closePreview}>Fechar</Button>
          </div>
          {/* PDF Content */}
          <div style={{ flex: 1, width: '100%', maxWidth: 900, overflow: 'hidden', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            {previewLoading ? (
              <div style={{ color: 'var(--tm-fg-3)', fontSize: 14, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 12 }}>
                <Icon name="loader" size={28} style={{ animation: 'spin 1s linear infinite' }} />
                <span>Carregando DANFE...</span>
              </div>
            ) : previewUrl ? (
              <iframe
                src={previewUrl}
                style={{ width: '100%', height: '100%', border: 'none', background: '#fff' }}
                title="DANFE Preview"
              />
            ) : (
              <div style={{ color: 'var(--tm-fg-3)', fontSize: 14 }}>Erro ao carregar DANFE</div>
            )}
          </div>
        </div>
      )}

      {/* Cancel NF-e Modal */}
      {cancelModal && (
        <div className="overlay" style={{ position: 'fixed', inset: 0, zIndex: 999, display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'rgba(0,0,0,0.5)' }}>
          <div style={{ background: 'var(--tm-bg-1)', borderRadius: 12, padding: 24, width: 440, boxShadow: '0 20px 60px rgba(0,0,0,0.3)' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 16 }}>
              <div style={{ width: 36, height: 36, borderRadius: 8, background: 'var(--tm-danger-bg, #fde8e8)', color: 'var(--tm-danger)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                <Icon name="alert-triangle" size={18} />
              </div>
              <div>
                <div style={{ fontWeight: 600, fontSize: 15 }}>Cancelar NF-e {cancelModal.numero}</div>
                <div className="muted" style={{ fontSize: 12 }}>Esta ação é irreversível e será transmitida à SEFAZ</div>
              </div>
            </div>
            <div style={{ marginBottom: 16 }}>
              <label style={{ display: 'block', fontSize: 12.5, fontWeight: 500, marginBottom: 6 }}>Motivo do cancelamento *</label>
              <textarea className="input" rows={3}
                placeholder="Informe o motivo (mínimo 15 caracteres, exigência SEFAZ)"
                value={cancelReason} onChange={e => setCancelReason(e.target.value)}
                style={{ width: '100%', resize: 'vertical', fontSize: 13 }} />
              {cancelReason.length > 0 && cancelReason.trim().length < 15 && (
                <div style={{ fontSize: 11, color: 'var(--tm-danger)', marginTop: 4 }}>Mínimo 15 caracteres ({cancelReason.trim().length}/15)</div>
              )}
            </div>
            <div style={{ display: 'flex', gap: 10, justifyContent: 'flex-end' }}>
              <Button variant="ghost" size="sm" onClick={() => { setCancelModal(null); setCancelReason(''); }} disabled={cancelling}>
                Voltar
              </Button>
              <Button variant="danger" size="sm" icon="x-circle"
                disabled={cancelling || cancelReason.trim().length < 15}
                onClick={handleCancel}>
                {cancelling ? 'Cancelando…' : 'Confirmar cancelamento'}
              </Button>
            </div>
          </div>
        </div>
      )}

      {/* Reemit Drawer for rejected NFs */}
      {reemitDrawer && (
        <NFEmissaoDrawer
          open={true}
          pedido={reemitDrawer.pedido}
          items={reemitDrawer.items}
          empresas={empresas}
          clienteData={reemitDrawer.clienteData}
          saving={reemitSaving}
          onEmitir={handleReemitSubmit}
          onCancel={() => setReemitDrawer(null)}
        />
      )}
    </div>
  );
}

// ─── 3. NFEmpresas ───────────────────────────────────────────────────────
function NFEmpresas({ onNav }) {
  const [empresas, setEmpresas] = useNfsState([]);
  const [loading, setLoading] = useNfsState(true);
  const [drawer, setDrawer] = useNfsState(null);
  const [saving, setSaving] = useNfsState(false);

  const load = useNfsCb(async () => {
    if (!window.tmSupabase) { setLoading(false); return; }
    setLoading(true);
    const { data } = await window.tmSupabase.from('empresas_emissoras').select('*').order('created_at');
    if (data) setEmpresas(data);
    setLoading(false);
  }, []);

  useNfsEffect(() => { load(); }, [load]);

  const openNew = () => {
    setDrawer({ ...BLANK_EMPRESA });
  };

  const openEdit = (emp) => {
    setDrawer({
      id: emp.id,
      razaoSocial: emp.razao_social || '',
      nomeFantasia: emp.nome_fantasia || '',
      cnpj: emp.cnpj || '',
      ie: emp.inscricao_estadual || '',
      im: emp.inscricao_municipal || '',
      regimeTributario: emp.regime_tributario || 'Simples Nacional',
      endereco: emp.endereco || { logradouro:'',numero:'',complemento:'',bairro:'',cidade:'',uf:'SP',cep:'' },
      telefone: emp.telefone || '',
      email: emp.email || '',
      ambiente: emp.ambiente || 'homologacao',
      serieNfe: emp.serie_nfe || 1,
      ativo: emp.ativo !== false,
      cor: emp.cor || '#C9A36B',
    });
  };

  const toggleAtivo = async (emp, e) => {
    e.stopPropagation();
    if (!window.tmSupabase) return;
    const novoStatus = !emp.ativo;
    const nome = emp.nome_fantasia || emp.razao_social;
    const acao = novoStatus ? 'ativar' : 'desativar';
    if (!confirm(`Deseja ${acao} a empresa "${nome}"?`)) return;
    const { error } = await window.tmSupabase.from('empresas_emissoras').update({ ativo: novoStatus, updated_at: new Date().toISOString() }).eq('id', emp.id);
    if (error) { alert('Erro: ' + error.message); return; }
    load();
  };

  const deleteEmpresa = async (emp, e) => {
    e.stopPropagation();
    const nome = emp.nome_fantasia || emp.razao_social;
    if (!confirm(`Tem certeza que deseja apagar a empresa "${nome}"?\n\nEssa ação não pode ser desfeita. Notas fiscais vinculadas a essa empresa NÃO serão apagadas.`)) return;
    if (!window.tmSupabase) return;
    // Check if empresa has notas fiscais
    const { count } = await window.tmSupabase.from('notas_fiscais').select('id', { count: 'exact', head: true }).eq('empresa_emissora_id', emp.id);
    if (count && count > 0) {
      alert(`Não é possível apagar "${nome}" pois existem ${count} nota(s) fiscal(is) vinculada(s) a essa empresa.\n\nDesative a empresa ao invés de apagar.`);
      return;
    }
    // Check if empresa is linked to pedidos
    const { count: pedCount } = await window.tmSupabase.from('pedidos').select('id', { count: 'exact', head: true }).eq('empresa_emissora_id', emp.id);
    if (pedCount && pedCount > 0) {
      alert(`Não é possível apagar "${nome}" pois existem ${pedCount} pedido(s) vinculado(s) a essa empresa.\n\nDesative a empresa ao invés de apagar.`);
      return;
    }
    const { error } = await window.tmSupabase.from('empresas_emissoras').delete().eq('id', emp.id);
    if (error) { alert('Erro ao apagar: ' + error.message); return; }
    load();
  };

  const saveEmpresa = async () => {
    if (!drawer || !drawer.razaoSocial?.trim() || !drawer.cnpj?.trim()) {
      alert('Razão social e CNPJ são obrigatórios.');
      return;
    }
    if (!window.tmSupabase) return;
    setSaving(true);
    const payload = {
      razao_social: drawer.razaoSocial.trim(),
      nome_fantasia: drawer.nomeFantasia?.trim() || null,
      cnpj: drawer.cnpj.trim(),
      inscricao_estadual: drawer.ie?.trim() || null,
      inscricao_municipal: drawer.im?.trim() || null,
      regime_tributario: drawer.regimeTributario,
      endereco: drawer.endereco || {},
      telefone: drawer.telefone?.trim() || null,
      email: drawer.email?.trim() || null,
      ambiente: drawer.ambiente,
      serie_nfe: parseInt(drawer.serieNfe) || 1,
      ativo: drawer.ativo,
      cor: drawer.cor || '#C9A36B',
      updated_at: new Date().toISOString(),
    };
    let error;
    if (drawer.id) {
      ({ error } = await window.tmSupabase.from('empresas_emissoras').update(payload).eq('id', drawer.id));
    } else {
      ({ error } = await window.tmSupabase.from('empresas_emissoras').insert(payload));
    }
    setSaving(false);
    if (error) { alert('Erro: ' + error.message); return; }
    setDrawer(null);
    load();
  };

  return (
    <div className="canvas">
      <PageHead title="Empresas Emissoras" sub="Gerencie os CNPJs habilitados para emissão de NF-e"
        right={<Button variant="primary" icon="plus" size="sm" onClick={openNew}>Nova empresa</Button>} />
      <NFTabs active="empresas" onNav={onNav} />

      {loading ? (
        <div style={{ padding: '60px 0', textAlign: 'center', color: 'var(--tm-fg-3)', fontSize: 13 }}>Carregando...</div>
      ) : empresas.length === 0 ? (
        <div style={{ padding: '60px 0', textAlign: 'center', color: 'var(--tm-fg-3)' }}>
          <Icon name="building-2" size={40} style={{ opacity: 0.3, marginBottom: 14 }} />
          <div style={{ fontSize: 15, marginBottom: 6 }}>Nenhuma empresa cadastrada</div>
          <div style={{ fontSize: 12.5, marginBottom: 16 }}>Cadastre pelo menos uma empresa para emitir NF-e</div>
          <Button variant="primary" icon="plus" size="sm" onClick={openNew}>Cadastrar empresa</Button>
        </div>
      ) : (
        <div className="grid-3">
          {empresas.map(emp => (
            <div key={emp.id} className="card" style={{ padding: 20, cursor: 'pointer' }} onClick={() => openEdit(emp)}>
              <div className="row between" style={{ marginBottom: 14 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                  <div style={{ width: 40, height: 40, borderRadius: 10, background: (emp.cor || '#C9A36B') + '22', color: emp.cor || '#C9A36B', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                    <Icon name="building-2" size={18} />
                  </div>
                  <div>
                    <div style={{ fontWeight: 600, fontSize: 14.5 }}>{emp.nome_fantasia || emp.razao_social}</div>
                    <div className="muted" style={{ fontSize: 11.5 }}>{emp.cnpj}</div>
                  </div>
                </div>
                <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                  <button onClick={(e) => toggleAtivo(emp, e)} title={emp.ativo ? 'Desativar empresa' : 'Ativar empresa'}
                    style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0 }}>
                    <Badge tone={emp.ativo ? 'success' : 'neutral'}>{emp.ativo ? 'Ativo' : 'Inativo'}</Badge>
                  </button>
                  <button onClick={(e) => deleteEmpresa(emp, e)} title="Apagar empresa"
                    style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 4, borderRadius: 6, color: 'var(--tm-fg-3)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}
                    onMouseEnter={e => e.currentTarget.style.color = 'var(--tm-danger)'}
                    onMouseLeave={e => e.currentTarget.style.color = 'var(--tm-fg-3)'}>
                    <Icon name="trash-2" size={15} />
                  </button>
                </div>
              </div>
              <div style={{ display: 'flex', gap: 16, paddingTop: 14, borderTop: '1px solid var(--tm-line-1)' }}>
                <div>
                  <div className="muted" style={{ fontSize: 10.5, textTransform: 'uppercase', letterSpacing: '0.08em' }}>Regime</div>
                  <div style={{ fontSize: 12.5, marginTop: 2 }}>{emp.regime_tributario || '—'}</div>
                </div>
                <div>
                  <div className="muted" style={{ fontSize: 10.5, textTransform: 'uppercase', letterSpacing: '0.08em' }}>Série</div>
                  <div style={{ fontSize: 12.5, marginTop: 2 }}>{emp.serie_nfe || 1}</div>
                </div>
                <div>
                  <div className="muted" style={{ fontSize: 10.5, textTransform: 'uppercase', letterSpacing: '0.08em' }}>Última NF</div>
                  <div style={{ fontSize: 12.5, marginTop: 2 }}>{emp.ultimo_numero_nfe || 0}</div>
                </div>
                <div>
                  <div className="muted" style={{ fontSize: 10.5, textTransform: 'uppercase', letterSpacing: '0.08em' }}>Certificado</div>
                  <div style={{ fontSize: 12.5, marginTop: 2 }}>
                    <Badge tone={emp.certificado_status === 'Válido' ? 'success' : emp.certificado_status === 'Vencido' ? 'danger' : 'neutral'}>
                      {emp.certificado_status || 'Não configurado'}
                    </Badge>
                  </div>
                </div>
              </div>
            </div>
          ))}
        </div>
      )}

      {drawer && (
        <EmpresaEmissoraForm
          open={!!drawer}
          empresa={drawer}
          setEmpresa={setDrawer}
          onSave={saveEmpresa}
          onCancel={() => setDrawer(null)}
          saving={saving}
        />
      )}
    </div>
  );
}

// ─── 4. NFImportarXml ────────────────────────────────────────────────────
function NFImportarXml({ onNav }) {
  return (
    <div className="canvas">
      <PageHead title="Importar XML" sub="Importe notas de entrada para o estoque" />
      <NFTabs active="importar" onNav={onNav} />
      <Card>
        <div style={{ padding: 40, textAlign: 'center', border: '2px dashed var(--tm-line-2)', borderRadius: 8, margin: 20 }}>
          <Icon name="upload-cloud" size={48} className="muted" />
          <div style={{ marginTop: 12, fontSize: 15 }}>Arraste arquivos XML aqui</div>
          <div className="muted" style={{ fontSize: 12, marginTop: 4 }}>ou clique para escolher · até 50 MB por upload</div>
          <Button variant="primary" icon="upload" size="md" style={{ marginTop: 16 }}>Escolher arquivos</Button>
        </div>
      </Card>
    </div>
  );
}

// ─── 5. NFLogs ───────────────────────────────────────────────────────────
function NFLogs({ onNav }) {
  const [logs, setLogs] = useNfsState([]);
  const [loading, setLoading] = useNfsState(true);

  useNfsEffect(() => {
    if (!window.tmSupabase) { setLoading(false); return; }
    setLoading(true);
    window.tmSupabase
      .from('nf_logs')
      .select('*, notas_fiscais(numero, serie)')
      .order('created_at', { ascending: false })
      .limit(100)
      .then(({ data }) => {
        if (data) setLogs(data);
        setLoading(false);
      });
  }, []);

  const fmtDate = (iso) => {
    if (!iso) return '—';
    return new Date(iso).toLocaleDateString('pt-BR', { day: '2-digit', month: '2-digit', year: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' });
  };

  const logTone = { info: 'info', warning: 'warning', error: 'danger', success: 'success' };

  return (
    <div className="canvas">
      <PageHead title="Logs · NF-e" sub="Registro de operações, rejeições e erros" />
      <NFTabs active="logs" onNav={onNav} />
      <Card>
        {loading ? (
          <div style={{ padding: '48px 0', textAlign: 'center', color: 'var(--tm-fg-3)', fontSize: 13 }}>Carregando...</div>
        ) : logs.length === 0 ? (
          <div style={{ padding: '48px 0', textAlign: 'center', color: 'var(--tm-fg-3)' }}>
            <Icon name="check-circle" size={36} style={{ opacity: 0.3, marginBottom: 12 }} />
            <div style={{ fontSize: 14, marginBottom: 6 }}>Nenhum log registrado</div>
            <div style={{ fontSize: 12 }}>Logs de emissão e erros aparecerão aqui</div>
          </div>
        ) : (
          <table className="tbl">
            <thead>
              <tr><th>Timestamp</th><th>NF Nº</th><th>Tipo</th><th>Mensagem</th></tr>
            </thead>
            <tbody>
              {logs.map(l => (
                <tr key={l.id}>
                  <td className="muted" style={{ fontSize: 12, whiteSpace: 'nowrap' }}>{fmtDate(l.created_at)}</td>
                  <td>
                    {l.notas_fiscais ? (
                      <span className="ref-mono">{l.notas_fiscais.numero}/{l.notas_fiscais.serie}</span>
                    ) : '—'}
                  </td>
                  <td><Badge tone={logTone[l.tipo] || 'neutral'}>{l.tipo}</Badge></td>
                  <td style={{ fontSize: 13 }}>{l.mensagem}</td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </Card>
    </div>
  );
}

// ─── Exports ─────────────────────────────────────────────────────────────
Object.assign(window, { NFEmissao, NFHistorico, NFEmpresas, NFImportarXml, NFLogs });
