// XLSX export usando SheetJS (XLSX global)

function sheetFromAOA(aoa, opts = {}) {
  const ws = XLSX.utils.aoa_to_sheet(aoa);
  if (opts.cols) ws['!cols'] = opts.cols;
  if (opts.merges) ws['!merges'] = opts.merges;
  return ws;
}

function formatXlsxDate(iso) {
  if (!iso) return '';
  const d = new Date(iso + 'T00:00:00');
  return `${String(d.getDate()).padStart(2, '0')}/${String(d.getMonth() + 1).padStart(2, '0')}/${d.getFullYear()}`;
}

// Exporta relatório de uma empresa
function exportEmpresaXLSX(empresa, lancs, portadores, centros, filename) {
  const wb = XLSX.utils.book_new();
  const hoje = todayISO();

  // 1) Sheet Geral
  const headerGeral = [
    ['RELATÓRIO FINANCEIRO - ' + empresa.nome],
    ['CNPJ: ' + empresa.cnpj, '', '', 'Gerado em: ' + formatXlsxDate(hoje)],
    [],
    ['Data Venc.', 'Competência', 'Tipo', 'Descrição', 'Centro de Custo', 'Portador', 'Forma Pgto', 'Valor', 'Status', 'Data Pgto', 'Comprovante']
  ];
  const portMap = Object.fromEntries(portadores.map(p => [p.id, p.nome]));
  const ccMap = Object.fromEntries(centros.map(c => [c.id, c.nome]));
  const ordered = [...lancs].sort((a, b) => a.vencimento.localeCompare(b.vencimento));
  ordered.forEach(l => {
    const s = lancStatus(l, hoje);
    headerGeral.push([
      formatXlsxDate(l.vencimento),
      l.competencia,
      l.tipo === 'entrada' ? 'Entrada' : 'Saída',
      l.descricao,
      ccMap[l.centroCustoId] || '',
      portMap[l.portadorId] || '',
      l.formaPagamento,
      l.valor,
      statusColor(s).label,
      l.pagamento ? formatXlsxDate(l.pagamento.data) : '',
      l.pagamento ? l.pagamento.comprovante : ''
    ]);
  });
  // Totals
  const totalEnt = lancs.filter(l => l.tipo === 'entrada').reduce((s, l) => s + l.valor, 0);
  const totalSai = lancs.filter(l => l.tipo === 'saida').reduce((s, l) => s + l.valor, 0);
  headerGeral.push([], ['', '', '', '', '', '', 'TOTAL ENTRADAS', totalEnt], ['', '', '', '', '', '', 'TOTAL SAÍDAS', totalSai], ['', '', '', '', '', '', 'RESULTADO', totalEnt - totalSai]);
  XLSX.utils.book_append_sheet(wb, sheetFromAOA(headerGeral, {
    cols: [{ wch: 12 }, { wch: 12 }, { wch: 9 }, { wch: 34 }, { wch: 22 }, { wch: 16 }, { wch: 14 }, { wch: 12 }, { wch: 11 }, { wch: 12 }, { wch: 18 }]
  }), 'Geral');

  // 2) Por Portador
  const aoaP = [['PORTADOR', 'Entradas', 'Saídas', 'Saldo Realizado', 'Qtd. Movs.']];
  const saldos = portadorSaldos(lancs, portadores);
  saldos.forEach(p => aoaP.push([p.nome, p.entradas, p.saidas, p.saldo, p.movs]));
  aoaP.push([], ['TOTAL', saldos.reduce((s, p) => s + p.entradas, 0), saldos.reduce((s, p) => s + p.saidas, 0), saldos.reduce((s, p) => s + p.saldo, 0), saldos.reduce((s, p) => s + p.movs, 0)]);
  XLSX.utils.book_append_sheet(wb, sheetFromAOA(aoaP, { cols: [{ wch: 22 }, { wch: 14 }, { wch: 14 }, { wch: 16 }, { wch: 12 }] }), 'Por Portador');

  // 3) Por Centro de Custo
  const aoaCC = [['CENTRO DE CUSTO', 'Tipo', 'Total', 'Pago/Recebido', 'Pendente', 'Qtd.']];
  const ccStats = centroCustoStats(lancs, centros);
  ccStats.forEach(c => aoaCC.push([c.nome, c.tipo === 'entrada' ? 'Entrada' : 'Saída', c.total, c.pago, c.pendente, c.qtd]));
  XLSX.utils.book_append_sheet(wb, sheetFromAOA(aoaCC, { cols: [{ wch: 30 }, { wch: 10 }, { wch: 14 }, { wch: 14 }, { wch: 14 }, { wch: 8 }] }), 'Por Centro de Custo');

  // 4) DRE Simplificado (por mês/competência)
  const meses = [...new Set(lancs.map(l => l.competencia))].sort((a, b) => {
    const [ma, ya] = a.split('/'); const [mb, yb] = b.split('/');
    return (ya + ma).localeCompare(yb + mb);
  });
  const aoaDRE = [['DRE SIMPLIFICADO POR COMPETÊNCIA'], [], ['Competência', ...meses, 'TOTAL']];
  function rowFor(label, filter) {
    const cells = meses.map(m => lancs.filter(l => l.competencia === m && filter(l)).reduce((s, l) => s + l.valor, 0));
    return [label, ...cells, cells.reduce((s, v) => s + v, 0)];
  }
  aoaDRE.push(rowFor('(+) Receitas', l => l.tipo === 'entrada'));
  aoaDRE.push(rowFor('(-) Despesas', l => l.tipo === 'saida'));
  centros.filter(c => c.tipo === 'saida').forEach(cc => {
    aoaDRE.push(rowFor('   ' + cc.nome, l => l.centroCustoId === cc.id));
  });
  const resultRow = ['= RESULTADO', ...meses.map(m => {
    const e = lancs.filter(l => l.competencia === m && l.tipo === 'entrada').reduce((s, l) => s + l.valor, 0);
    const sa = lancs.filter(l => l.competencia === m && l.tipo === 'saida').reduce((s, l) => s + l.valor, 0);
    return e - sa;
  })];
  resultRow.push(resultRow.slice(1).reduce((s, v) => s + v, 0));
  aoaDRE.push(resultRow);
  XLSX.utils.book_append_sheet(wb, sheetFromAOA(aoaDRE, { cols: [{ wch: 32 }, ...meses.map(() => ({ wch: 12 })), { wch: 14 }] }), 'DRE Simplificado');

  XLSX.writeFile(wb, filename || `Relatorio - ${empresa.nome}.xlsx`);
}

// Exporta consolidado multi-empresa
function exportConsolidadoXLSX(empresas, allLancs, portadores, centros, filename = 'Consolidado BPO.xlsx') {
  const wb = XLSX.utils.book_new();
  const hoje = todayISO();
  const portMap = Object.fromEntries(portadores.map(p => [p.id, p.nome]));
  const ccMap = Object.fromEntries(centros.map(c => [c.id, c.nome]));
  const empMap = Object.fromEntries(empresas.map(e => [e.id, e.nome]));

  // 1) Resumo por empresa
  const aoaRes = [['CONSOLIDADO BPO - Gerado em ' + formatXlsxDate(hoje)], [], ['Empresa', 'CNPJ', 'Recebido', 'A Receber', 'Pago', 'A Pagar', 'Vencidos', 'Saldo']];
  empresas.forEach(e => {
    const ls = allLancs[e.id] || [];
    const st = empresaStats(e, ls, hoje);
    aoaRes.push([e.nome, e.cnpj, st.recebido, st.aReceber, st.pago, st.aPagar, st.vencidos, st.saldo]);
  });
  XLSX.utils.book_append_sheet(wb, sheetFromAOA(aoaRes, { cols: [{ wch: 32 }, { wch: 20 }, ...Array(6).fill({ wch: 14 })] }), 'Resumo Empresas');

  // 2) Todos lançamentos
  const aoa = [['Empresa', 'Data', 'Comp.', 'Tipo', 'Descrição', 'Centro Custo', 'Portador', 'Forma Pgto', 'Valor', 'Status']];
  empresas.forEach(e => {
    const ls = allLancs[e.id] || [];
    ls.forEach(l => {
      const s = lancStatus(l, hoje);
      aoa.push([
        empMap[e.id], formatXlsxDate(l.vencimento), l.competencia,
        l.tipo === 'entrada' ? 'Entrada' : 'Saída',
        l.descricao, ccMap[l.centroCustoId] || '', portMap[l.portadorId] || '',
        l.formaPagamento, l.valor, statusColor(s).label
      ]);
    });
  });
  XLSX.utils.book_append_sheet(wb, sheetFromAOA(aoa, { cols: [{ wch: 28 }, { wch: 12 }, { wch: 10 }, { wch: 9 }, { wch: 30 }, { wch: 22 }, { wch: 16 }, { wch: 14 }, { wch: 12 }, { wch: 11 }] }), 'Todos Lançamentos');

  // 3) Por Portador (consolidado)
  const aoaP = [['Portador', ...empresas.map(e => e.nome), 'TOTAL']];
  portadores.forEach(p => {
    const row = [p.nome];
    let total = 0;
    empresas.forEach(e => {
      const v = (allLancs[e.id] || []).filter(l => l.portadorId === p.id && l.pago).reduce((s, l) => s + (l.tipo === 'entrada' ? l.valor : -l.valor), 0);
      row.push(v); total += v;
    });
    row.push(total);
    aoaP.push(row);
  });
  XLSX.utils.book_append_sheet(wb, sheetFromAOA(aoaP, { cols: [{ wch: 22 }, ...empresas.map(() => ({ wch: 18 })), { wch: 14 }] }), 'Por Portador');

  // 4) Por Centro de Custo
  const aoaCC = [['Centro de Custo', 'Tipo', ...empresas.map(e => e.nome), 'TOTAL']];
  centros.forEach(c => {
    const row = [c.nome, c.tipo === 'entrada' ? 'Entrada' : 'Saída'];
    let total = 0;
    empresas.forEach(e => {
      const v = (allLancs[e.id] || []).filter(l => l.centroCustoId === c.id).reduce((s, l) => s + l.valor, 0);
      row.push(v); total += v;
    });
    row.push(total);
    aoaCC.push(row);
  });
  XLSX.utils.book_append_sheet(wb, sheetFromAOA(aoaCC, { cols: [{ wch: 28 }, { wch: 10 }, ...empresas.map(() => ({ wch: 18 })), { wch: 14 }] }), 'Por Centro de Custo');

  XLSX.writeFile(wb, filename);
}

function exportarBackup(data, filename = 'Backup_Completo.xlsx') {
  const wb = XLSX.utils.book_new();

  // 1) Empresas
  const empAoa = [['ID', 'Nome', 'Nome Fantasia', 'CNPJ', 'Segmento', 'Email', 'Telefone', 'Criada Em']];
  data.empresas.forEach(e => {
    empAoa.push([e.id, e.nome, e.nomeFantasia, e.cnpj, e.segmento, e.email, e.telefone, formatXlsxDate(e.criadaEm)]);
  });
  XLSX.utils.book_append_sheet(wb, XLSX.utils.aoa_to_sheet(empAoa), 'Empresas');

  // 2) Lançamentos
  const lancAoa = [['ID', 'Empresa', 'Descrição', 'Valor', 'Tipo', 'Vencimento', 'Competência', 'Pago', 'Data Pagamento', 'Comprovante']];
  data.empresas.forEach(e => {
    (data.lancamentos[e.id] || []).forEach(l => {
      lancAoa.push([l.id, e.nome, l.descricao, l.valor, l.tipo, formatXlsxDate(l.vencimento), l.competencia, l.pago ? 'Sim' : 'Não', l.pagamento ? formatXlsxDate(l.pagamento.data) : '', l.pagamento?.comprovante || '']);
    });
  });
  XLSX.utils.book_append_sheet(wb, XLSX.utils.aoa_to_sheet(lancAoa), 'Lançamentos');

  // 3) Portadores
  const portAoa = [['ID', 'Nome', 'Conta', 'Agência', 'Instituição']];
  data.portadores.forEach(p => {
    portAoa.push([p.id, p.nome, p.conta || '', p.agencia || '', p.banco || '']);
  });
  XLSX.utils.book_append_sheet(wb, XLSX.utils.aoa_to_sheet(portAoa), 'Portadores');

  // 4) Centros de Custo
  const ccAoa = [['ID', 'Nome', 'Tipo']];
  data.centrosCusto.forEach(c => {
    ccAoa.push([c.id, c.nome, c.tipo]);
  });
  XLSX.utils.book_append_sheet(wb, XLSX.utils.aoa_to_sheet(ccAoa), 'Centros de Custo');

  XLSX.writeFile(wb, filename);
}

Object.assign(window, { exportEmpresaXLSX, exportConsolidadoXLSX, exportarBackup });
