const database = require('../config/database')
const response = require("../constants/response");
const pagination = require("../constants/pagination");
const logger = require('../services/loggerService');
const paginationRecords = require("../helpers/paginationRecords")
const { clientesTransacoesFilteres, clientesTransacoesSomatorioFilteres } = require('../helpers/filterResponseSQL');


module.exports.getTransacoes = async function(pagina, limite, total_registros, entidade, montante, pagamento, referencia, percentagem_actual, minimo_actual, maximo_actual, valor_total, req) { 
     
      try{

        logger("SERVIDOR:getPagamentos").debug("Á carregar dados com limite")
        const transaccoes = await database('transaccoes')
        .whereLike("pagamento",`%${pagamento}%`)
        .whereLike("montante_da_transaccao",`%${montante}%`)
        .whereLike("referencia_da_transacao",`%${referencia}%`)
        .whereLike("entidade",`%${entidade}%`)
        .whereLike("percentagem_actual",`%${percentagem_actual}%`)
        .whereLike("minimo_actual",`%${minimo_actual}%`)
        .whereLike("maximo_actual",`%${maximo_actual}%`)
        .whereLike("valor_total",`%${valor_total}%`)
        .limit(total_registros || pagination.total_limite)
        .orderBy('id_transaccao','desc')     
        
        
        const {registros} = paginationRecords(transaccoes, pagina, limite)

        logger("SERVIDOR:getPagamentos").debug("Á carregar dados com limite")
        const transaccoesLimite = await  database('transaccoes')
        .whereLike("pagamento",`%${pagamento}%`)
        .whereLike("montante_da_transaccao",`%${montante}%`)
        .whereLike("referencia_da_transacao",`%${referencia}%`)
        .whereLike("entidade",`%${entidade}%`)
        .whereLike("percentagem_actual",`%${percentagem_actual}%`)
        .whereLike("minimo_actual",`%${minimo_actual}%`)
        .whereLike("maximo_actual",`%${maximo_actual}%`)
        .whereLike("valor_total",`%${valor_total}%`)
        .limit(registros.limite)
        .offset(registros.count)
        .orderBy('id_transaccao','desc')  
        
        registros.total_apresentados = transaccoesLimite.length
        registros.entidade = entidade
        registros.referencia = referencia
        registros.montante = montante
        registros.pagamento = pagamento
        registros.referencia = referencia
        registros.percentagem_actual = percentagem_actual
        registros.minimo_actual = minimo_actual
        registros.maximo_actual = maximo_actual 
        registros.valor_total = valor_total
        
      
        delete registros.count
        
        logger("SERVIDOR:getPagamentos").info("Respondendo a requisição")
        const rs = response("sucesso", 200, transaccoesLimite, "json",
        {
          registros,
          url: req.originalUrl
        });
            
        return rs

      
     } catch (error) {
        console.error(error.message)
        logger("SERVIDOR:getPagamentos").error("Erro a buscar os dados "+error.message)
        const rs = response("erro", 400, 'Algo aconteceu. Tente de novo');
        return rs
    }
    
}

module.exports.getTransacoesId = async function(id_transaccao, req) {
     
  try{
      const [transaccoes] = await database('transaccoes')
      .where({id_transaccao})
      .orderBy('id_transaccao','desc') 
      
      logger("SERVIDOR:getPagamentos").info("Respondendo a requisição")
      const rs = response("sucesso", 200, transaccoes || {}, "json",
      {
        url: req.originalUrl
      });
          
      return rs
  
  } catch (error) {
      console.error(error.message)
      logger("SERVIDOR:getPagamentos").error("Erro a buscar os dados "+error.message)
      const rs = response("erro", 400, 'Algo aconteceu. Tente de novo');
      return rs
  }
    
}

module.exports.getTransacoesPagamento = async function(pagamento, req) {
     
     try{
        const [transaccoes] = await database('transaccoes')
        .join("pagamentos","pagamentos.id_pagamento","=","transaccoes.pagamento")
        .where({pagamento})
        .orderBy('id_transaccao','desc')

        logger("SERVIDOR:getPagamentos").info("Respondendo a requisição")
        const rs = response("sucesso", 200, transaccoes || {}, "json",
        {
          url: req.originalUrl
        });
            
        return rs 
      
     } catch (error) {
        console.error(error.message)
        logger("SERVIDOR:getPagamentos").error("Erro a buscar os dados "+error.message)
        const rs = response("erro", 400, 'Algo aconteceu. Tente de novo');
        return rs
     }
    
}

module.exports.getTransacoesPorEntidade = async function(numero_entidade, pagina, limite,  total_registros, req) {
     
     try{

        const verifivarPagamentoTempoReal = await database('configuracoes').where({cliente_entidade: numero_entidade})        

        if((verifivarPagamentoTempoReal[0]?.servico_pagamento_por_sector == "false") && (verifivarPagamentoTempoReal[0]?.servico_gpo == "false")){
          return {status:"erro", mensagem:"Serviço de pagamento por sector inactivo"}      
        }
        
        const transaccoes = await database('transaccoes')
        .join("clientes","clientes.numero_entidade","=","transaccoes.entidade")
        .join("percentagem_por_uso","percentagem_por_uso.id_por_uso","=","clientes.percentagem_de_uso")
        .where({entidade: numero_entidade})
        .limit(total_registros || pagination.total_limite)
        .orderBy('id_transaccao','desc')
        
        const {registros} = paginationRecords(transaccoes, pagina, limite)

        logger("SERVIDOR:getPagamentos").debug("Á carregar dados com limite")
        const transaccoesLimite = await database('transaccoes')
        .join("clientes","clientes.numero_entidade","=","transaccoes.entidade")
        .join("percentagem_por_uso","percentagem_por_uso.id_por_uso","=","clientes.percentagem_de_uso")      
        .where({entidade: numero_entidade})
        .limit(registros.limite)
        .offset(registros.count)
        .orderBy('id_transaccao','desc') 
        
        delete registros.count

        const filtered = clientesTransacoesFilteres(transaccoesLimite)
          
        logger("SERVIDOR:getPagamentos").info("Respondendo a requisição")
        const rs = response("sucesso", 200, filtered, "json",
        {
          registros,
          url: req.originalUrl

        });
            
        return rs
      
     } catch (error) {
        console.error(error.message)
        logger("SERVIDOR:getPagamentos").error("Erro a buscar os dados "+error.message)
        const rs = response("erro", 400, 'Algo aconteceu. Tente de novo');
        return rs
    }
    
}

module.exports.getTransacoesAgrudadoPorEntidadeSomatoriaDiario = async function(data, req) {
     
     try{
      
        const dataDiario = data || new Date().toISOString().split("T")[0]
        const transaccoes = await database('transaccoes')
        .where("tempo_transacao", "LIKE", `${dataDiario}%`)
        .orderBy('id_transaccao','desc')

        const clientes = await database('clientes')
        .join("percentagem_por_uso","percentagem_por_uso.id_por_uso","=","clientes.percentagem_de_uso")
        .orderBy("id_clientes","DESC")
        
        const filtered = clientesTransacoesSomatorioFilteres(transaccoes, clientes)        
        
        logger("SERVIDOR:getPagamentos").info("Respondendo a requisição")
        const rs = response("sucesso", 200, filtered, "json",
        {
          url: req.originalUrl
        });
            
        return rs 
    
    } catch (error) {
        console.error(error.message)
        logger("SERVIDOR:getPagamentos").error("Erro a buscar os dados "+error.message)
        const rs = response("erro", 400, 'Algo aconteceu. Tente de novo');
        return rs
    }
    
}

module.exports.getTransacoesAgrudadoPorEntidadeSomatoriaMensal = async function(data, req) {
     
    try{
        
        const dataMensal = data || new Date().toISOString().split("T")[0].substring(0,7)
        const transaccoes = await database('transaccoes')
        .where("tempo_transacao", "LIKE", `${dataMensal}%`)
        .orderBy('id_transaccao','desc')

        const clientes = await database('clientes')
        .join("percentagem_por_uso","percentagem_por_uso.id_por_uso","=","clientes.percentagem_de_uso")
        .orderBy("id_clientes","DESC")
        
        const filtered = clientesTransacoesSomatorioFilteres(transaccoes, clientes)        
        
        logger("SERVIDOR:getPagamentos").info("Respondendo a requisição")
        const rs = response("sucesso", 200, filtered, "json",
        {
          url: req.originalUrl
        });
            
        return rs 
    
    } catch (error) {
        console.error(error.message)
        logger("SERVIDOR:getPagamentos").error("Erro a buscar os dados "+error.message)
        const rs = response("erro", 400, 'Algo aconteceu. Tente de novo');
        return rs
    }
    
}

module.exports.getTransacoesAgrudadoPorEntidadeSomatoria = async function(req) {
     
    try{    

        const transaccoes = await database('transaccoes')
        .orderBy('id_transaccao','desc')

        const clientes = await database('clientes')
        .join("percentagem_por_uso","percentagem_por_uso.id_por_uso","=","clientes.percentagem_de_uso")
        .orderBy("id_clientes","DESC")

        const filtered = clientesTransacoesSomatorioFilteres(transaccoes, clientes)        
        
        logger("SERVIDOR:getPagamentos").info("Respondendo a requisição")
        const rs = response("sucesso", 200, filtered, "json",
        {
          url: req.originalUrl
        });
            
        return rs 
    
    } catch (error) {
      console.error(error.message)
      logger("SERVIDOR:getPagamentos").error("Erro a buscar os dados "+error.message)
      const rs = response("erro", 400, 'Algo aconteceu. Tente de novo');
      return rs
    }
    
}

module.exports.getTransacoesAgrudadoPorEntidadeSomatoriaEntidade = async function(entidade, req) {
     
     try{
      
        const transaccoes = await database('transaccoes')
        .where({entidade})
        .orderBy('id_transaccao','desc')

        const clientes = await database('clientes')
        .join("percentagem_por_uso","percentagem_por_uso.id_por_uso","=","clientes.percentagem_de_uso")
        .where({numero_entidade: entidade})
        .orderBy("id_clientes","DESC")

        const [filtered] = clientesTransacoesSomatorioFilteres(transaccoes, clientes)        
        
        logger("SERVIDOR:getPagamentos").info("Respondendo a requisição")
        const rs = response("sucesso", 200, filtered, "json",
        {
          url: req.originalUrl
        });
            
        return rs 
    
    } catch (error) {
        console.error(error.message)
        logger("SERVIDOR:getPagamentos").error("Erro a buscar os dados "+error.message)
        const rs = response("erro", 400, 'Algo aconteceu. Tente de novo');
        return rs
    }
    
}


module.exports.getTransacoesAgrudadoPorEntidadeSomatoriaEntidadeMensalidades = async function(entidade, req) {
     
  try{
   

   const somatorioMensais = [];

   const anoCorrente = new Date().getFullYear().toString();

   for (let index = 1; index <= 12; index++) {

     const mes = index.toString().length == 1 ? "0".concat(index.toString()) : index.toString()

     const transaccoes = await database('transaccoes')
     .where("tempo_transacao", "LIKE", `%${anoCorrente}-${mes}%`)
     .andWhere({entidade})
     .orderBy('id_transaccao','desc')

     const clientes = await database('clientes')
     .where({numero_entidade: entidade})
     .join("percentagem_por_uso","percentagem_por_uso.id_por_uso","=","clientes.percentagem_de_uso")
     .orderBy("id_clientes","DESC")
       
      const [filtered] = clientesTransacoesSomatorioFilteres(transaccoes, clientes)        
      

      filtered.mensalidade = `${anoCorrente}-${mes}`
      somatorioMensais.push(filtered);
   }
   
   logger("SERVIDOR:getPagamentos").info("Respondendo a requisição")
   const rs = response("sucesso", 200, somatorioMensais, "json",
   {
     url: req.originalUrl
   });
       
   return rs 
   
  } catch (error) {
      console.error(error.message)
      logger("SERVIDOR:getPagamentos").error("Erro a buscar os dados "+error.message)
      const rs = response("erro", 400, 'Algo aconteceu. Tente de novo');
      return rs
  }
 
}

module.exports.getTransacoesAgrudadoPorEntidade = async function(pagina, limite, total_registros, req) {
     
     try{
      

        const transaccoes = await database('transaccoes')
        .join("clientes","clientes.numero_entidade","=","transaccoes.entidade")
        .join("percentagem_por_uso","percentagem_por_uso.id_por_uso","=","clientes.percentagem_de_uso")
        .limit(total_registros || pagination.total_limite)
        .orderBy('id_transaccao','desc')
        
        const {registros} = paginationRecords(transaccoes, pagina, limite)

        logger("SERVIDOR:getPagamentos").debug("Á carregar dados com limite")
        const transaccoesLimite = await database('transaccoes')
        .join("clientes","clientes.numero_entidade","=","transaccoes.entidade")
        .join("percentagem_por_uso","percentagem_por_uso.id_por_uso","=","clientes.percentagem_de_uso")     
        .limit(registros.limite)
        .offset(registros.count)
        .orderBy('id_transaccao','desc') 
        
        delete registros.count

        const filtered = clientesTransacoesFilteres(transaccoesLimite)
          
        logger("SERVIDOR:getPagamentos").info("Respondendo a requisição")
        const rs = response("sucesso", 200, filtered, "json",
        {
          registros,
          url: req.originalUrl

        });
            
        return rs
      
     } catch (error) {
        console.error(error.message)
        logger("SERVIDOR:getPagamentos").error("Erro a buscar os dados "+error.message)
        const rs = response("erro", 400, 'Algo aconteceu. Tente de novo');
        return rs
    }
    
}

module.exports.getTransacoesPorEntidadeDias = async function(numero_entidade, dia_inicio, dia_final) {
     
     try{

      const verifivarPagamentoTempoReal = await database('configuracoes').where({cliente_entidade: numero_entidade})        

      if((verifivarPagamentoTempoReal[0]?.servico_pagamento_por_sector == "false") && (verifivarPagamentoTempoReal[0]?.servico_gpo == "false")){
        logger("SERVIDOR:getPagamentosEntidadeReferencia").info("Serviço de pagamento por sector inactivo")
          const rs = response("erro", 423, "Serviço de pagamento por sector inactivo");
          return rs      
      }

      const pag = await database('transaccoes')
      .join("pagamentos","pagamentos.id_pagamento","=","transaccoes.pagamento")
      .whereBetween("tempo_transacao",[dia_inicio, dia_final])
      .andWhere({numero_entidade})
      .orderBy('id_transaccao','desc')

      const clientes = await database('clientes')
      .where({numero_entidade})
      .join("percentagem_por_uso","percentagem_por_uso.id_por_uso","=","clientes.percentagem_de_uso")
      
      const dados = [];
    for (const iterator of clientes) {
      const registo = [];
      delete iterator.senha;
      delete iterator.tipo_produto;
      delete iterator.tipo_registo;
      // delete iterator.nome_empresa;
      delete iterator.nif;
      delete iterator.contacto;
      delete iterator.email;
      delete iterator.criando_em;
      delete iterator.feito_em;
      //delete iterator.logo;
      delete iterator.bloqueio;
      for (const i of pag) {
        if (iterator.numero_entidade == i.entidade) {
          registo.push(i);
          delete i.senha;
          delete i.cliente;
          delete i.tipo_registo;
          delete i.id_clientes;
          delete i.nome_empresa;
          delete i.tipo_produto;
          delete i.nif;
          delete i.contacto;
          delete i.email;
          delete i.criando_em;
          ////delete i.logo;
          delete i.id_tipo_produto;
          // delete i.numero_entidade;
          delete i.comunicacao;
          delete i.num_padrao_referencias;
          delete i.responsavel;
          delete i.senha;
          delete i.bloqueio;
        }
      }
      iterator.registo = registo;
      dados.push(iterator);
    }
      
      
      return {status:"sucesso", mensagem:dados}
      
     } catch (error) {
      console.error(error.message)
      return {status:"erro", mensagem:"Algo aconteceu. Tente de novo"}
    }
    
}

module.exports.getTransacoesEntidadeDias = async function(entidade, dia_inicio, dia_final, pagina, limite, req) {
     
     try{

        const verifivarPagamentoTempoReal = await database('configuracoes').where({cliente_entidade: entidade})        

        if((verifivarPagamentoTempoReal[0]?.servico_pagamento_por_sector == "false") && (verifivarPagamentoTempoReal[0]?.servico_gpo == "false")){
            logger("SERVIDOR:getPagamentosEntidadeReferencia").info("Serviço de pagamento por sector inactivo")
            const rs = response("erro", 423, "Serviço de pagamento por sector inactivo");
            return rs   
        }

        const transaccoes = await database('transaccoes')
        .whereBetween("tempo_transacao",[dia_inicio, dia_final])
        .andWhere({entidade})
        .orderBy('id_transaccao','desc')

        const {registros} = paginationRecords(transaccoes, pagina, limite)

        logger("SERVIDOR:getPagamentos").debug("Á carregar dados com limite")
        const transaccoesLimite = await  database('transaccoes')
        .where({entidade})
        .whereBetween("tempo_transacao",[dia_inicio, dia_final])
        .limit(registros.limite)
        .offset(registros.count)
        .orderBy('id_transaccao','desc') 
        
        delete registros.count
          
        logger("SERVIDOR:getPagamentos").info("Respondendo a requisição")
        const rs = response("sucesso", 200, transaccoesLimite, "json",
        {
          registros,
          url: req.originalUrl

        });
            
        return rs
      
     } catch (error) {
        console.error(error.message)
        logger("SERVIDOR:getPagamentos").error("Erro a buscar os dados "+error.message)
        const rs = response("erro", 400, 'Algo aconteceu. Tente de novo');
        return rs
    }
    
}

module.exports.getTransacoesDias = async function(dia_inicio, dia_final, pagina, limite, req) {
     
     try{
      const transaccoes = await database('transaccoes')
        .whereBetween("tempo_transacao",[dia_inicio, dia_final])
        .orderBy('id_transaccao','desc')

        const {registros} = paginationRecords(transaccoes, pagina, limite)

        logger("SERVIDOR:getPagamentos").debug("Á carregar dados com limite")
        const transaccoesLimite = await  database('transaccoes')
        .whereBetween("tempo_transacao",[dia_inicio, dia_final])
        .limit(registros.limite)
        .offset(registros.count)
        .orderBy('id_transaccao','desc') 
        
        delete registros.count
          
        logger("SERVIDOR:getPagamentos").info("Respondendo a requisição")
        const rs = response("sucesso", 200, transaccoesLimite, "json",
        {
          registros,
          url: req.originalUrl

        });
            
        return rs
      
     } catch (error) {
        console.error(error.message)
        logger("SERVIDOR:getPagamentos").error("Erro a buscar os dados "+error.message)
        const rs = response("erro", 400, 'Algo aconteceu. Tente de novo');
        return rs
    }
    
}

module.exports.postRelatorioTransacao = async function({entidade, campos}) {

    
  try {

    const filename = new Date().toISOString().split('Z')[0].replaceAll('-','').replaceAll('T','').replaceAll(':','').replaceAll('.','')+'.xlsx'    

    if(true){
      const transacoes =  await database('pagamentos')
      .select('tempo_transacao as DATA DA TRANSACAO', 
      'numero_Log_EGR as NÚMERO LOG EGR',
      'Identificacao_Log_EGR as IDENTIFICAÇAO LOG EGR',
      'montante_da_operacao as MONTANTE DA OPERAÇÃO',
      'referencia_do_servico as REFERÊNCIA',
      'percentagem_actual as PERCENTAGEM ACTUAL',
      'minimo_actual as MINIMO A COBRAR',
      'maximo_actual as MAXIMO A COBRAR',
      'valor_total as VALOR TOTAL')
      .join("transaccoes","transaccoes.pagamento","=","pagamentos.id_pagamento")
      .where({numero_entidade: entidade})
      .andWhere("tempo_transacao", "LIKE", `${campos.tempo_transacao}%`) 
      

      transacoes.map(function(fn){
        fn["DATA DA TRANSACAO"] = fn["DATA DA TRANSACAO"] ? new Date(fn["DATA DA TRANSACAO"]).toLocaleDateString() : "AGUARDAR CONCILIAÇÃO"
        fn["MONTANTE DA OPERAÇÃO"] = Intl.NumberFormat("PT-br").format(Number(fn["MONTANTE DA OPERAÇÃO"]))
        fn["VALOR TOTAL"] = Intl.NumberFormat("PT-br").format(Number(fn["VALOR TOTAL"]))

        return fn
      })

      logger("SERVIDOR:Clientes").info("Respondeu a solicitação")
      const rs = response("sucesso", 201, {transacoes, filename});
      return rs
    }
    

    
  } catch (error) {
      console.error(error.message)
      logger("SERVIDOR:getPagamentos").error("Erro a buscar os dados "+error.message)
      const rs = response("erro", 400, 'Algo aconteceu. Tente de novo');
      return rs
}
  
}

module.exports.postTransacaoPesquisar = async function (dados, pagina, limite) {

  
  try {

      const transaccoes = await database('transaccoes')
      .where({entidade: dados.entidade_cliente})
      .andWhere('referencia_da_transacao', 'LIKE', `%${dados.referencia_da_transacao}%`, 'OR', 'referencia_da_transacao', 'IS null')
      .andWhere('montante_da_transaccao', 'LIKE', `%${dados.montante_da_transaccao}%`, 'OR', 'montante_da_transaccao', 'IS null')
      .andWhere('tempo_transacao', 'LIKE', `%${dados.tempo_transacao}%`, 'OR','tempo_transacao', 'IS NULL')
      .andWhere('pagamento', 'LIKE', `%${dados.pagamento}%`, 'OR','pagamento', 'IS NULL')
      .orderBy('id_transaccao','desc')
      
      const {registros} = paginationRecords(transaccoes, pagina, limite)

      const transaccoesLimite = await database('transaccoes')
      .where({entidade: dados.entidade_cliente})
      .andWhere('referencia_da_transacao', 'LIKE', `%${dados.referencia_da_transacao}%`, 'OR', 'referencia_da_transacao', 'IS null')
      .andWhere('montante_da_transaccao', 'LIKE', `%${dados.montante_da_transaccao}%`, 'OR', 'montante_da_transaccao', 'IS null')
      .andWhere('tempo_transacao', 'LIKE', `%${dados.tempo_transacao}%`, 'OR','tempo_transacao', 'IS NULL')
      .andWhere('pagamento', 'LIKE', `%${dados.pagamento}%`, 'OR','pagamento', 'IS NULL')
      .limit(registros.limite)
      .offset(registros.count)
      .orderBy('id_transaccao','desc')  
      
      delete registros.count
      
      logger("SERVIDOR:getPagamentos").info("Respondendo a requisição")
      const rs = response("sucesso", 200, transaccoesLimite, "json",
      {
        registros,
        url: req.originalUrl
      });
          
      return rs
      
    
  } catch (error) {
      console.error(error.message)
      logger("SERVIDOR:getPagamentos").error("Erro a buscar os dados "+error.message)
      const rs = response("erro", 400, 'Algo aconteceu. Tente de novo');
      return rs
  }
};

