$("#tutorial").on("click", function () {
  $(document).ready(async function () {
    const driver = new Driver({
      doneBtnText: "Sair",
      closeBtnText: "Fechar",
      nextBtnText: "Próximo",
      prevBtnText: "Anterior",
      allowClose: false,
    });
    driver.defineSteps([
      {
        element: "#btnFiltros",
        popover: {
          title: "Botão Filtros",
          description:
            "Clique aqui para ter acesso aos filtros e iniciar uma consulta das posições.",
          position: "right",
        },
      },
      {
        element: "#btnIncluir",
        popover: {
          title: "Botão Incluir",
          description:
            "Clique aqui para iniciar o cadastro de uma posição.",
          position: "right",
        },
      },
      {
        element: "#btnImprimir",
        popover: {
          title: "Botão Imprimir",
          description: "Clique aqui para imprimir os dados.",
          position: "top",
        },
      },
      {
        element: "#tabelaDados",
        popover: {
          title: "Tabela",
          description: "Aqui estão os dados das posições.",
          position: "top",
        },
      },
    ]);
    driver.start();
  });
});


$(document).ready(async function () {
  const permissaoUsuarioLogado = await permissaoAcessos("EXTRATO_CARTAO");
  window.databody = {}

  function parseExcel(file) {
    var reader = new FileReader();

    reader.onload = function (e) {
      var data = e.target.result;
      var workbook = XLSX.read(data, {
        type: 'binary'
      });

      workbook.SheetNames.forEach(function (sheetName) {
        var XL_row_object = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
        var json_object = JSON.stringify(XL_row_object);
        console.log(json_object);
      })
    };

    reader.onerror = function (ex) {
      console.log(ex);
    };

    reader.readAsBinaryString(file);
  };

  async function leArquivoXLS(file) {
    var file = document.querySelector('#mdModalUpload').files[0];
    var name = file.name.toUpperCase();
    var reader = new FileReader();

    reader.onload = function (e) {
      var data = e.target.result;
      var cfb = XLS.CFB.read(data, { type: 'binary' });
      var wb = XLS.parse_xlscfb(cfb);
      wb.SheetNames.forEach(function (sheetName) {
        var sCSV = XLS.utils.make_csv(wb.Sheets[sheetName]);

        const objRetorno = transformStringEmArray(sCSV);
        $('#conteudoFormatado').val(JSON.stringify(objRetorno));
      });
    };
    reader.readAsBinaryString(file);
  }

  function transformStringEmArray(string) {
    let newObj = {}
    const linhas = string.trim().split('\n');

    let cabecalhoIndex = 0;
    for (let i = 0; i < linhas.length; i++) {
      if (linhas[i].startsWith("Status,Tipo de Lançamento")) {
        cabecalhoIndex = i;
        break;
      }
    }
    const dadosSemCabecalho = linhas.slice(cabecalhoIndex);

    const cabecalho = dadosSemCabecalho[0].split(',');
    const dados = [];

    for (let i = 1; i < dadosSemCabecalho.length; i++) {
      let noEmpty = dadosSemCabecalho[i].replace(/,,/g, ',-,');
      if (noEmpty.endsWith(',')) {
        noEmpty = noEmpty.slice(0, -1) + ',-';
      }
      const colunas = noEmpty.match(/(".*?"|[^",]+)/g);

      const objeto = {};

      for (let j = 0; j < cabecalho.length; j++) {
        objeto[cabecalho[j]] = colunas[j];
      }

      dados.push(objeto);

      newObj = dados.map((item) => ({
        status: item['Status'],
        tipoLancamento: item['Tipo de Lançamento'],
        descricao: item['Descrição'],
        banco: item['Banco'],
        agencia: item['Agência'],
        conta: item['Conta'],
        gravame: item['Gravame'],
        instituicaoCnpj: item['CNPJ da instituição origem da negociação'],
        instituicaoNome: item['Nome da instituição origem da negociação'],
        estabelecimento: item['Estabelecimento'],
        dataPagamento: item['Data de pagamento'],
        dataLancamento: item['Data do lançamento'],
        dataAutorizacao: item['Data da autorização da venda'],
        bandeira: item['Bandeira'],
        formaPagamento: item['Forma de Pagamento'],
        parcela: item['Número da parcela'],
        quantidadeParcelas: item['Quantidade de parcelas'],
        numeroCartão: item['Número do cartão'],
        codigoTransação: item['Código da transação'],
        tID: item['TID'],
        codigoAutorização: item['Código de autorização'],
        nsu: item['NSU'],
        valorBruto: removeCaracteres(item['Valor bruto']),
        valorLiquido: removeCaracteres(item['Valor líquido']),
        valorPendente: removeCaracteres(item['Valor pendente']),
        recebaRapido: removeCaracteres(item['Receba Rápido']),
        tipoCaptura: removeCaracteres(item['Tipo de captura']),
        taxaAntecipacao: removeCaracteres(item['Taxa de antecipação']),
        valorEntrada: removeCaracteres(item['Valor da entrada']),
        taxas: removeCaracteres(item['Taxas (%)']),
        codigoVenda: item['Código da venda'],
        numeroMaquina: item['Número da máquina'],
        periodoConsiderado: item['Período considerado'],
        numeroOperacao: item['Número da operação'],
        fatura: item['Número da nota fiscal'],
        ID: item['ID'],
        valorDescontado: item['Valor descontado'],
        valorTotal: item['Valor total'],
        canalVenda: item['Canal de venda'],
        resumoOperacao: item['Resumo da operação'],
        tarifa: item['Tarifa'],
        taxaEmbarque: item['Taxa de embarque'],
        numeroPedido: item['Número do pedido'],
      }));
    }

    return newObj;
  }

  function retornaArrayFormatado(array) {
    const header = array[1]
    const novoArray = array.slice(2, -1).map((dados, i) => {
      const data = []
      dados.map((item, k) => {
        data[header[k]] = item
      })
      return data
    })

    return novoArray
  }

  const CarregaHeader = {
    //caso for necessário adicionar outro extrato, só bota os campos do arquivo em aqui em baixo seguindo o mesmo padrão
    "belluno": {
      'taxaAntec': 'Antecipação (R$)',
      'bandeira': 'Bandeira',
      'taxa': 'Captura (R$)',
      'cliente': 'Cliente',
      'data': 'Data Crédito',
      'dataVenda': 'Data Venda',
      'nsu': 'Documento',
      'parcela': 'Documento',
      'estornado': 'Estornado (R$)',
      'prazo': 'Prazo',
      'taxaTran': 'Tarifa de transação (R$)',
      'taxaCaptura': 'Taxa Captura',
      'tipo': 'Tipo',
      'totalParcelas': 'Total Parcelas',
      'valorBruto': 'Valor Bruto(R$)',
      'valorLiquido': 'Valor Líquido(R$)',
    },
  }

  function formatarValor(valor) {
    if (typeof valor !== 'string') {
      valor = valor.toString();
    }

    if (valor.match(/^\d{1,3}(\.\d{3})+,\d{2}$/)) {
      return valor.replace(/\./g, '');
    }

    if (valor.match(/^\d+(\.\d{2})$/)) {
      return valor.replace('.', ',');
    }

    if (valor.match(/^\d+,\d{2}$/)) {
      return valor;
    }

    return valor;
  };

  async function leArquivoXLSX(arquivo, belluno = false) {
    const file = extraiNome(arquivo.name.toUpperCase())
    try {
      let rows = await readXlsxFile(arquivo);
      const array = retornaArrayFormatado(rows)
      const objeto = array
        .map(item => {
          const novoObjeto = {};

          //Caso for necessário adicionar qualquer outro extrato que seja no padrão genérico CSV, é só adicionar os campos do arquivo no objeto CarregaHeaderCSV seguindo o padrão que eu montei
          for (const chave in CarregaHeader[file]) {
            const valor = item[CarregaHeader[file][chave]] ? item[CarregaHeader[file][chave]].toString() : item[CarregaHeader[file][chave]];
            // console.log({ item, file, chave })
            if (valor) {
              if (chave.toLowerCase().includes('valor')) {
                novoObjeto[chave] = formatarValor(valor);
              } else {
                novoObjeto[chave] = valor.replace('.', ',');
              }
            }
          }

          return novoObjeto;
        });

      return { objeto, file }

    } catch (err) {
      console.log(err)
    }
  }

  function somarDias(dataBase, diasASomar) {
    const dataResultante = new Date(dataBase);
    dataResultante.setDate(dataResultante.getDate() + diasASomar);
    return dataResultante;
  }

  async function leArquivoXLSXRede(arquivo) {
    const dataBase = new Date(1899, 11, 30);

    // --- FUNÇÃO PARA TRATAR DATA ---
    const parseRedeDate = (value) => {
      if (value == null || value === "") return null;

      let date;

      if (value instanceof Date) {
        date = value;
      } else if (typeof value === "number") {
        date = somarDias(dataBase, value);
      } else if (typeof value === "string") {
        const p = value.split("/");
        if (p.length === 3) {
          date = new Date(Number(p[2]), Number(p[1]) - 1, Number(p[0]));
        } else {
          return null;
        }
      } else {
        return null;
      }

      if (!date || isNaN(date.getTime())) return null;

      return formataData(date) + "T00:00:00.000Z";
    };

    // --- FUNÇÃO PARA TRATAR NÚMEROS COM VÍRGULA ---
    const parseNumero = (valor) => {
      if (valor === null || valor === undefined) return 0;

      if (typeof valor === "number") return valor || 0;

      const str = valor.toString().trim();
      if (!str) return 0;

      const normalizado = str.replace(/\./g, "").replace(",", ".");
      const n = parseFloat(normalizado);
      return isNaN(n) ? 0 : n;
    };

    try {
      let rows = await readXlsxFile(arquivo);

      let objeto = rows.map((dados) => ({
        // datas
        dataRecebimento: parseRedeDate(dados[0]),
        dataPagamento: parseRedeDate(dados[0]),
        dataOriginalVenda: parseRedeDate(dados[1]),
        dataOriginalVencimento: parseRedeDate(dados[2]),

        // valores tratados com parseNumero
        valorBruto: parseNumero(dados[3]),
        valorDuplicata: parseNumero(dados[3]),
        // dados[4] existe no arquivo, mas você não usa
        valorTaxa: parseNumero(dados[5]),
        valorMDRDescontado: parseNumero(dados[6]),
        valorTarifa: parseNumero(dados[6]),
        valorLiquido: parseNumero(dados[7]),

        negociada: dados[8],
        percentual: dados[9],
        nsu: dados[10],
        TID: dados[11],
        numeroPedido: dados[12],
        numeroAutorizacao: dados[13],
        resumoVendasNumeroLote: dados[14],
        nomeEstabelecimento: dados[15],
        estabelecimento: dados[16],
        numeroCartao: dados[17],
        indicadorTransacaoTokenizada: dados[18],
        codigoIATA: dados[19],
        modalidade: dados[20],
        bandeira: dados[21],
        numeroParcelas: dados[22],
        parcela: dados[23],
        banco: dados[24],
        agencia: dados[25],
        contaCorrente: dados[26],
        cancelamentoContestacao: dados[27],

        dataCancelamento: parseRedeDate(dados[28]),

        status: dados[29],
      }));

      objeto = objeto.splice(1);

      return objeto;

    } catch (err) {
      console.log(err);
    }
  }

  async function leArquivoStone(arquivo) {
    try {
      let rows = await readXlsxFile(arquivo);
      if (rows.length < 2) {
        throw new Error('O arquivo não contém dados suficientes.');
      }
      //Recebe a primeira posição do array pois é o cabeçalho
      const cabecalho = rows[0];
      //Recebe o restante das informações
      const dadosSemCabecalho = rows.slice(1);
      //Monta o novo nome do cabeçalho com base no que veio no arquivo, verificar que podem ser unificados os model no backend futuramente
      const novoNome = {
        'STONE ID': 'nsu',
        'BANDEIRA': 'bandeira',
        'VALOR BRUTO': 'valor',
        'VALOR BRUTO': 'valorPago',
        'DESCONTO DE MDR': 'valorTarifa',
        'DESCONTO DE ANTECIPAÇÃO': 'taxaAntecipacao',
        'DATA DO ÚLTIMO STATUS': 'dataPagamento',
        'Nº DA PARCELA': 'parcela',
        'VALOR LÍQUIDO': 'valorLiquido',
        'DATA DE VENCIMENTO': 'dataVencimento',
        'ÚLTIMO STATUS': 'ultimoStatus',
        'CATEGORIA': 'categoria',
        'CHAVE EXTERNA': 'chaveExterna',
        'DOCUMENTO': 'documento',
        'HORA DA VENDA': 'horaVenda',
        'NOME FANTASIA': 'nomeFantasia',
        'N° CARTÃO': 'numeroCartao',
        'N° DA PARCELA': 'numeroParcela',
        'QTD DE PARCELAS': 'quantidadeParcelas',
        'STONECODE': 'stoneCode',
        'TIPO': 'tipo',
      };

      const objeto = dadosSemCabecalho.map((dados, i) => {
        const objetoLinha = {};
        //Aqui ele pega o cabeçalho e substitui pelo novo ao longo do loop, depois insere o dado respectivo dentro do objetoLinha (nsu: 123456)
        cabecalho.forEach((coluna, j) => {
          const nomePropriedade = novoNome[coluna] || coluna;
          if (nomePropriedade == 'horaVenda' || nomePropriedade == 'dataPagamento') {
            objetoLinha[nomePropriedade] = formataDateTimeTZ(dados[j])
          } else if (nomePropriedade == 'dataVencimento') {
            // objetoLinha[nomePropriedade] = formataDateBarraHifen(dados[j])
            objetoLinha[nomePropriedade] = dados[j].split('/').reverse().join('-');
          } else {
            objetoLinha[nomePropriedade] = dados[j]
          }
        });
        return objetoLinha;
      });

      return objeto;

    } catch (err) {
      console.log(err)
    }
  }

  const mapeamentoArquivos = {
    //aqui fiz esse objeto pra encontrar o header depois de acordo com o nome que eu quero, pode ser util e fica mais bonitinho
    "MAGAPAY": "magapay",
    "BELLUNO": "belluno",
    "STONE": "stone",
  };

  const CarregaHeaderCSV = {
    //caso for necessário adicionar outro extrato, só bota os campos do arquivo em aqui em baixo seguindo o mesmo padrão
    "magapay": {
      'data': 'Data',
      'dataVencimento': '',
      'descricao': 'Descricao',
      'iDTransacao': 'ID Transacao',
      'iDTransferencia': 'ID Transferencia',
      'lojista': 'Lojista',
      'operacao': 'Operacao',
      'parcela': 'Parcela',
      'nsu': 'Pedido',
      'pedidoPagamento': 'Pedido Pagamento',
      'valorTotal': 'Pedido Total',
      'valorFrete': 'Pedido Valor Frete',
      'valorAcrescimo': 'Pedido Valor Acrescimo',
      'desconto': 'Pedido Valor Desconto',
      'valorProduto': 'Pedido Valor Produto',
      'taxas': 'Taxas',
      'tipo': 'Tipo',
      'valorBruto': 'Valor Bruto',
      'valorLiquido': 'Valor Liquido',
    },
    "stone": {
      "valorBruto": 'Valor Bruto Stonr'
    }
  }

  function extraiNome(arquivo) {
    //busca o nome bonitinho
    for (const chave in mapeamentoArquivos) {
      if (arquivo.includes(chave)) {
        return mapeamentoArquivos[chave];
      }
    }
    return '';
  }

  function leArquivoCSV(arquivo) {
    const file = extraiNome(arquivo.name.toUpperCase())
    if (!arquivo) {
      return msgAlerta('Nenhum arquivo identificado')
    }

    return new Promise((resolve, reject) => {
      const campos = []
      Papa.parse(arquivo, { //essa lib PapaParser pelo que vi tem alguns parametros interessantes que podem ser passados, caso precise de algo novo da uma olhada https://www.papaparse.com/, pode ajudar
        header: true,
        skipEmptyLines: true,
        complete: (results) => {
          try {
            const objeto = results.data
              .filter(item => item.Pedido && item.Pedido.trim() !== '')
              .map(item => {
                const novoObjeto = {};

                //Caso for necessário adicionar qualquer outro extrato que seja no padrão genérico CSV, é só adicionar os campos do arquivo no objeto CarregaHeaderCSV seguindo o padrão que eu montei
                for (const chave in CarregaHeaderCSV[file]) {
                  const valor = item[CarregaHeaderCSV[file][chave]];
                  if (campos.length != results.meta.fields.length) {
                    campos.push(chave)
                  }
                  if (valor) {
                    novoObjeto[chave] = valor;
                  }
                }

                return novoObjeto;
              });

            resolve({ objeto, file, campos });
          } catch (error) {
            reject(error);
          }
        },
        error: (error) => {
          reject(error);
        }
      });
    });
  }

  function alteraAba(novaAba) {
    $('.abaLink.active').removeClass('active');
    $('.tab-content .active').removeClass('active show');

    $(`#tab${novaAba}`).addClass('active')
    $(`#div${novaAba}`).addClass('active').addClass('show')
  }

  $(async function () {
    var modalUploadArquivo = $("#mdModalUpload");
    var BotaoArquivo = $("#btnArquivo");
    BotaoArquivo.click(function () {
      modalUploadArquivo.click();
    });

    modalUploadArquivo.change(async function () {
      let dataFile = document.querySelector('#mdModalUpload').files[0];
      let fileName = dataFile.name.toUpperCase();

      $('#txtArquivo').val(fileName)
      let readerArchive = new FileReader();

      readerArchive.onload = async function (e) {
        let fileContent = e.target.result;
        $('#conteudoFormatado').val(fileContent);
      };
      if (fileName.indexOf('PAGARME') !== -1) {
        if (fileName.indexOf('.XLSX') !== -1 || fileName.indexOf('.XLS') !== -1) {
          $('#tabGenerico').html(fileName)
        }
      }
      else if (fileName.indexOf('MAGAPAY') !== -1) {
        if (fileName.indexOf('.CSV') !== -1 || fileName.indexOf('.TXT') !== -1) {
          $('#tabGenericoCSV').html(fileName)
          alteraAba('GenericoCSV')

          leArquivoCSV(dataFile)
            .then((objeto) => {
              window.databody = objeto;
            })
            .catch((erro) => {
              console.error('Erro ao ler o arquivo:', erro);
            });
        }
      }
      else if (fileName.indexOf('BELLUNO') !== -1) {
        alteraAba('Generico')
        $('#tabGenerico').html(fileName)
        $('#txtArquivoBelluno').val('true');

        leArquivoXLSX(dataFile, true)
          .then((objeto) => {
            window.databody = objeto;
          })
          .catch((erro) => {
            console.error('Erro ao ler o arquivo:', erro);
          });
      }
      else if (fileName.indexOf('STONE') !== -1) {
        alteraAba('Stone')
        $('#txtNomeArquivoStone').val(fileName)
        let stone = await leArquivoStone(dataFile)
        $('#conteudoFormatado').val(JSON.stringify(stone));
      }
      else if (fileName.indexOf('CIELO') !== -1 && (fileName.indexOf('.XLXS') !== -1 || fileName.indexOf('.XLS') !== -1)) {
        alteraAba('Cielo')
        $('#txtNomeArquivoCielo').val(fileName)
        let cielo = await leArquivoXLS(dataFile)
        $('#conteudoFormatado').val(JSON.stringify(cielo));
      }
      else if ((fileName.indexOf('REDE') !== -1 || fileName.indexOf('.XLSX') !== -1 || (fileName.indexOf('CMP') !== -1 || fileName.indexOf('REDECARD') !== -1) || fileName.indexOf('CMP') !== -1) && fileName.indexOf('VINDI') === -1 && fileName.indexOf('ASAAS') === -1 && fileName.indexOf('MAGAZORD') === -1 && fileName.indexOf('GETNET') === -1) {
        alteraAba('Rede')
        let rede = await leArquivoXLSXRede(dataFile)
        console.log(rede)
        $('#conteudoFormatado').val(JSON.stringify(rede));
        $('#txtNomeArquivoRede').val(fileName)
      }
      // else if (fileName.indexOf('CIELO') !== -1 || fileName.indexOf('.TXT') !== -1) {
      //   alteraAba('Cielo')
      //   $('#txtNomeArquivoCielo').val(fileName)
      //   readerArchive.readAsText(dataFile)
      // }
      else if (fileName.indexOf('GETNET') !== -1) {
        alteraAba('Getnet');
        let getnet = await leArquivoXLSXGetnet(dataFile);
        $('#conteudoFormatado').val(JSON.stringify(getnet));
        window.databody = getnet;
      }
      else if (fileName.indexOf('SAFRA') !== -1) {
        alteraAba('Safra')
        $('#txtNomeArquivoSafra').val(fileName)
        readerArchive.readAsText(dataFile)
      } else if (fileName.indexOf('PAGSEG') !== -1) {
      } else if (fileName.toUpperCase().indexOf('VINDI') !== -1) {
        alteraAba('Vindi');
        let vindi = await leArquivoXLSXVindi(dataFile);
        $('#conteudoFormatado').val(JSON.stringify(vindi));
        window.databody = vindi;
      } else if (fileName.toUpperCase().indexOf('ASAAS') !== -1) {
        alteraAba('Asaas');
        let asaas = await leArquivoXLSXAsaas(dataFile);
        $('#conteudoFormatado').val(JSON.stringify(asaas));
        window.databody = asaas;
      } else if (fileName.toUpperCase().indexOf('MAGAZORD') !== -1) {
        alteraAba('Magazord');
        let magazord = await leArquivoXLSXMagazord(dataFile);
        $('#conteudoFormatado').val(JSON.stringify(magazord));
        window.databody = magazord;
      } else {
        throw msgAlerta('Não foi possível ler o extrato.')
      }
    });
  });

  async function leArquivoXLSXAsaas(file) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();

      reader.onload = function (e) {
        try {
          const data = new Uint8Array(e.target.result);
          const workbook = XLSX.read(data, { type: 'array' });
          const sheet = workbook.Sheets[workbook.SheetNames[0]];


          let rows = XLSX.utils.sheet_to_json(sheet, { header: 1 });


          rows = rows.slice(2);


          const header = rows.shift();


          const registros = rows.map(r => {
            const obj = {};
            header.forEach((col, index) => {
              obj[col] = r[index];
            });
            return obj;
          });

          const resultado = [];

          registros.forEach(row => {


            let valor = parseFloat(row["Valor"]) || 0;
            if (valor <= 0) return


            const idTransacao = row["Fatura da cobrança"]?.toString().trim() || "";

            if (!idTransacao) return


            const parcela = 1;

            const nossoNumero = `${idTransacao}/${parcela}`;


            let dataPagamento = "";
            const dataStr = row["Data"];

            if (dataStr) {
              if (typeof dataStr === "string" && dataStr.includes("/")) {
                const [dia, mes, ano] = dataStr.split("/");
                dataPagamento = `${ano}-${mes}-${dia}`;
              } else {
                const dt = new Date(dataStr);
                dataPagamento = dt.toISOString().split("T")[0];
              }
            }


            resultado.push({
              sel: "",
              nsu: idTransacao,
              nosso_numero: nossoNumero,
              valor: valor,
              valor_pago: valor,
              tarifa: 0,
              taxa_antec: 0,
              dt_pagamento: dataPagamento,
              parcela: parcela,
              valor_liquido: valor,
              dt_vencimento: dataPagamento
            });

          });

          resolve(resultado);

        } catch (erro) {
          reject(erro);
        }
      };

      reader.onerror = reject;
      reader.readAsArrayBuffer(file);
    });
  }

  async function leArquivoXLSXVindi(file) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();

      reader.onload = function (e) {
        try {
          const data = new Uint8Array(e.target.result);
          const workbook = XLSX.read(data, { type: 'array' });
          const sheet = workbook.Sheets[workbook.SheetNames[0]];
          const rows = XLSX.utils.sheet_to_json(sheet);

          const resultado = [];

          rows.forEach(row => {
            const valorBruto = parseFloat(row['Valor Bruto']) || 0;
            if (valorBruto !== 0) {
              const idTransacao = row['ID Transação']?.toString().trim() || '';
              const parcelasRaw = (row['Parcelas'] || '-').toString().trim();
              const valorLiquido = parseFloat(row['Valor Liq.']) || 0;
              const taxaRetencao = parseFloat(row['Taxa Retenção']) || 0;
              const taxaAntecipacao = parseFloat(row['Taxa Antecipação']) || 0;
              let dataPagamento = '';
              try {
                dataPagamento = row['Data']
                  ? new Date(row['Data']).toISOString().split('T')[0]
                  : '';

              } catch (error) {
                const dataStr = row['Data'];

                if (dataStr) {
                  const [dia, mes, resto] = dataStr.split('/');
                  const [ano, hora] = resto.split(' ');
                  const iso = `${ano}-${mes}-${dia}T${hora}`;
                  dataPagamento = new Date(iso).toISOString().split('T')[0];
                }
              }

              let parcela = '1';
              if (parcelasRaw.includes('de')) {
                parcela = parcelasRaw.split('de')[0].trim();
              } else if (parcelasRaw !== '-') {
                parcela = parcelasRaw;
              }

              const nossoNumero = `${idTransacao}/${parcela}`;

              resultado.push({
                sel: '',
                nsu: idTransacao,
                nosso_numero: nossoNumero,
                valor: valorBruto,
                valor_pago: valorBruto,
                tarifa: taxaRetencao,
                taxa_antec: taxaAntecipacao,
                dt_pagamento: dataPagamento,
                parcela: parseInt(parcela, 10) || 1,
                valor_liquido: valorLiquido,
                dt_vencimento: dataPagamento
              });
            }
          });

          resolve(resultado);
        } catch (erro) {
          reject(erro);
        }
      };

      reader.onerror = reject;
      reader.readAsArrayBuffer(file);
    });
  }

  async function leArquivoXLSXMagazord(file) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();

      const parseNumero = (valor) => {
        if (valor === null || valor === undefined) return 0;
        if (typeof valor === 'number') return valor || 0;

        const str = valor.toString().trim();
        if (!str) return 0;

        const normalizado = str.replace(/\./g, '').replace(',', '.');
        const n = parseFloat(normalizado);
        return isNaN(n) ? 0 : n;
      };

      function excelToISO(serial) {
        const d = XLSX.SSF.parse_date_code(serial);
        if (!d) return null;
        const jsDate = new Date(d.y, d.m - 1, d.d);
        return jsDate.toISOString().split("T")[0];
      }

      reader.onload = function (e) {
        try {
          const data = new Uint8Array(e.target.result);
          const workbook = XLSX.read(data, { type: 'array' });
          const sheet = workbook.Sheets[workbook.SheetNames[0]];
          const rows = XLSX.utils.sheet_to_json(sheet, { defval: '' });

          const resultado = [];

          rows.forEach(row => {

            const textoTotal = (v) =>
              typeof v === 'string' && v.trim().toLowerCase() === 'total';

            if (
              textoTotal(row['Data Crédito - Inicio']) ||
              textoTotal(row['Data Crédito - Fim']) ||
              textoTotal(row['Valor Bruto'])
            ) return;

            const idTransacao = row['NSU']?.toString().trim() || '';
            if (!idTransacao) return;

            const valorBruto = parseNumero(row['Valor Bruto']);
            if (valorBruto === 0) return;

            const valorTaxa = parseNumero(row['Valor Taxa']);
            const valorLiquido = parseNumero(row['Valor Líquido']);

            let dataPagamento = row['Data Crédito - Fim'];

            if (typeof dataPagamento === 'number') {
              dataPagamento = excelToISO(dataPagamento);
            }

            if (
              !dataPagamento ||
              (typeof dataPagamento === 'string' &&
                dataPagamento.trim().toLowerCase() === 'total')
            ) return;


            const parcelas =
              row['Parcela'] ??
              row['Nº Parcela'] ??
              row['Qtd. Parcelas'] ??
              null;

            const parcelasRaw = (parcelas ?? '1').toString().trim();
            const numeroParcela = parseInt(parcelasRaw, 10) || 1;

            const nossoNumero = `${idTransacao}/${numeroParcela}`;

            resultado.push({
              sel: '',
              nsu: idTransacao,
              nosso_numero: nossoNumero,
              valor: valorBruto,
              valor_pago: valorBruto,
              tarifa: valorTaxa,
              taxa_antec: 0,
              dt_pagamento: dataPagamento,
              parcela: numeroParcela,
              valor_liquido: valorBruto,
              dt_vencimento: dataPagamento
            });
          });

          resolve(resultado);
        } catch (erro) {
          reject(erro);
        }
      };

      reader.onerror = reject;
      reader.readAsArrayBuffer(file);
    });
  }

  async function leArquivoXLSXGetnet(file) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();

      const parseNumero = (valor) => {
        if (valor === null || valor === undefined) return 0;
        if (typeof valor === "number") return valor || 0;

        const str = valor.toString().trim();
        if (!str || str === "-") return 0;

        const normalizado = str.replace(/\./g, "").replace(",", ".");
        const n = parseFloat(normalizado);
        return isNaN(n) ? 0 : n;
      };

      const pad2 = (n) => String(n).padStart(2, "0");

      function excelToISO(serial) {
        const d = XLSX.SSF.parse_date_code(serial);
        if (!d) return null;
        return `${d.y}-${pad2(d.m)}-${pad2(d.d)}`;
      }

      function dateToISO(v) {
        if (!v) return null;

        if (v instanceof Date && !isNaN(v.getTime())) {
          return `${v.getFullYear()}-${pad2(v.getMonth() + 1)}-${pad2(v.getDate())}`;
        }

        if (typeof v === "number") return excelToISO(v);

        const s = v.toString().trim();
        if (!s || s === "-") return null;

        const mBR = s.match(/^(\d{2})\/(\d{2})\/(\d{4})/);
        if (mBR) return `${mBR[3]}-${mBR[2]}-${mBR[1]}`;

        const mISO = s.match(/^(\d{4})-(\d{2})-(\d{2})/);
        if (mISO) return `${mISO[1]}-${mISO[2]}-${mISO[3]}`;

        return null;
      }

      const getField = (row, keys) => {
        for (const k of keys) {
          const v = row?.[k];
          if (v !== undefined && v !== null && String(v).trim() !== "") return v;
        }
        return "";
      };

      function encontrarLinhaCabecalho(sheet) {
        const ref = sheet["!ref"];
        if (!ref) return 0;

        const range = XLSX.utils.decode_range(ref);
        const maxScan = Math.min(range.e.r, 120);

        for (let R = range.s.r; R <= maxScan; R++) {
          let achouNSU = false;
          let achouEC = false;
          let achouValor = false;

          for (let C = range.s.c; C <= range.e.c; C++) {
            const addr = XLSX.utils.encode_cell({ r: R, c: C });
            const cell = sheet[addr];
            if (!cell || cell.v === undefined || cell.v === null) continue;

            const txt = String(cell.v).trim().toLowerCase();
            if (!txt) continue;

            if (txt.includes("nsu")) achouNSU = true;
            if (txt === "ec centralizador") achouEC = true;
            if (txt.includes("valor") && (txt.includes("liquid") || txt.includes("parcela") || txt.includes("venda")))
              achouValor = true;
          }

          if (achouNSU && (achouEC || achouValor)) return R; 
        }

        return 0;
      }

      reader.onload = function (e) {
        try {
          const data = new Uint8Array(e.target.result);
          const workbook = XLSX.read(data, { type: "array", cellDates: true });

          const sheet =
            workbook.Sheets["Detalhado"] ||
            workbook.Sheets[workbook.SheetNames[0]];

          const headerRow = encontrarLinhaCabecalho(sheet);

          const rows = XLSX.utils.sheet_to_json(sheet, {
            defval: "",
            range: headerRow, 
          });

          const resultado = [];

          rows.forEach((row) => {
            const idTransacaoRaw = getField(row, [
              "NÚMERO COMPROVANTE DE VENDA (NSU)",
              "NUMERO COMPROVANTE DE VENDA (NSU)",
              "NSU",
            ]);

            const idTransacao = (idTransacaoRaw ?? "").toString().trim();
            if (!idTransacao || idTransacao === "-" || idTransacao.toLowerCase() === "total") return;

            const parcelasRaw = getField(row, ["PARCELAS", "Parcela", "Nº Parcela", "Qtd. Parcelas"]);
            const parcelasStr = (parcelasRaw ?? "1").toString().trim();
            const mParc = parcelasStr.match(/(\d+)/);
            const numeroParcela = (mParc ? parseInt(mParc[1], 10) : 1) || 1;

            const nossoNumero = `${idTransacao}/${numeroParcela}`;

            const valorBruto = parseNumero(
              getField(row, ["VALOR DA PARCELA", "VALOR DA VENDA", "VALOR LIQUIDADO", "VALOR LÍQUIDO"])
            );
            if (valorBruto === 0) return;

            const descontos = parseNumero(getField(row, ["DESCONTOS", "Valor Taxa", "VALOR TAXA"]));
            const valorTaxa = Math.abs(descontos) || 0;

            const valorLiquido = parseNumero(
              getField(row, ["VALOR LIQUIDO DA PARCELA", "VALOR LIQUIDADO", "VALOR LÍQUIDO"])
            );

            const dataPagamentoISO = dateToISO(getField(row, ["DATA DE VENCIMENTO", "Data de Vencimento"]));
            if (!dataPagamentoISO) return;

            resultado.push({
              sel: "",
              nsu: idTransacao,
              nosso_numero: nossoNumero,
              valor: valorBruto,
              valor_pago: valorBruto,
              tarifa: valorTaxa,
              taxa_antec: 0,
              dt_pagamento: dataPagamentoISO,
              parcela: numeroParcela,
              valor_liquido: valorLiquido || (valorBruto - valorTaxa),
              dt_vencimento: dataPagamentoISO,
            });
          });

          resolve(resultado);
        } catch (erro) {
          reject(erro);
        }
      };

      reader.onerror = reject;
      reader.readAsArrayBuffer(file);
    });
  }

});
