$("#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]);
        // var oJS = XLS.utils.sheet_to_row_object_array(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)
    try {
      let rows = await readXlsxFile(arquivo);
      const objeto = rows.slice(2, -1).map((dados) => ({
        dataRecebimento: formataData(somarDias(dataBase, dados[0])) + 'T00:00:00.000Z',
        dataOriginalVenda: formataData(somarDias(dataBase, dados[1])) + 'T00:00:00.000Z',
        dataOriginalVencimento: formataData(somarDias(dataBase, dados[2])) + 'T00:00:00.000Z',
        valorBruto: dados[3],
        valorDuplicata: dados[3],
        valorTaxa: dados[5],
        valorMDRDescontado: dados[6],
        valorLiquido: 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: dados[28],
        status: dados[29],
      }));
      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)

        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) {
        alteraAba('Rede')
        let rede = await leArquivoXLSXRede(dataFile)
        $('#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) {
      }
      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')) {
        alteraAba('Vindi');
        $('#txtNomeArquivoVindi').val(fileName); 
        let vindi = await leArquivoXLSXVindi(dataFile);
        $('#conteudoFormatado').val(JSON.stringify(vindi));
        window.databody = vindi;
      } else {
        throw msgAlerta('Não foi possível ler o extrato.')
      }
    });
  });

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;
            const dataPagamento = row['Data']
              ? new Date(row['Data']).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);
    });
  }
});
