const database = require('../config/database')
const REF = require("../controllers/referencias")
var parseString = require('xml2js').parseString;


module.exports.getReferencia = async function (pagina, limite) {
  try {
   
    const referencias = await database('referencias')
      .join("tipo_produto","tipo_produto.id_tipo_produto","=","referencias.tipo_de_registro")      
      .join("produtos_clientes","produtos_clientes.id_produto","=","referencias.indicador_produto_id")
      .orderBy('id_referencia','DESC')

      const numero_registros = referencias.length;
      const registroPorPagina =  +limite || 100
      let  pagina_actual = +pagina  || 1;
      let total_paginas = Math.ceil(numero_registros/registroPorPagina); 
      
      if(pagina_actual == "0") pagina_actual = 1;
      if(registroPorPagina == "0") registroPorPagina = 100;
      
      let count = (pagina_actual * registroPorPagina) - registroPorPagina;
      
      const referenciasLimite = await database('referencias')
      .join("tipo_produto","tipo_produto.id_tipo_produto","=","referencias.tipo_de_registro")      
      .join("produtos_clientes","produtos_clientes.id_produto","=","referencias.indicador_produto_id")
      .limit(registroPorPagina)
      .offset(count)
      .orderBy('id_referencia','DESC')
      
      
      return {status: "sucesso", registros: {paginas: total_paginas, pagina_actual, total: numero_registros, total_apresentados: referenciasLimite.length, limite: registroPorPagina}, mensagem: referenciasLimite}
    

  } catch (error) {
    console.log(error);
    return { status: "erro", mensagem: "Algo aconteceu. Tente de novo!" };
  }
};

module.exports.getReferenciaId = async function (id_referencia) {
  try {
    const referencias = await database("referencias")
      .join(
        "tipo_produto",
        "tipo_produto.id_tipo_produto",
        "=",
        "referencias.tipo_de_registro"  
      )
      .join(
        "produtos_clientes",
        "produtos_clientes.id_produto",
        "=",
        "referencias.indicador_produto_id"
      )
      // .join("tipo_produto_cliente","tipo_produto_cliente.tipo_registo","=","tipo_produto.id_tipo_produto")
      .where({ id_referencia })
      .orderBy("id_referencia", "DESC");
    return { status: "sucesso", mensagem: referencias };
  } catch (error) {
    console.log(error);
    return { status: "erro", mensagem: "Algo aconteceu. Tente de novo!" };
  }
};

module.exports.getReferenciaReferencia = async function (
  num_referencia,
) {
  try {


    const referencias = await database("referencias")
      .join(
        "tipo_produto",
        "tipo_produto.id_tipo_produto",
        "=",
        "referencias.tipo_de_registro"
      )
      .join(
        "produtos_clientes",
        "produtos_clientes.id_produto",
        "=",
        "referencias.indicador_produto_id"
      )
      // .join("tipo_produto_cliente","tipo_produto_cliente.tipo_registo","=","tipo_produto.id_tipo_produto")
      .where({ num_referencia })
      // .andWhere({entidade_cliente: numero_entidade})
      .orWhere({ referencia_do_montante: num_referencia })
      .orderBy("id_referencia", "DESC");
    return { status: "sucesso", mensagem: referencias };
  } catch (error) {
    console.log(error);
    return { status: "erro", mensagem: "Algo aconteceu. Tente de novo!" };
  }
};

module.exports.getReferenciaReferenciaEntidade = async function (
  num_referencia,
  numero_entidade
) {
  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 invativo"}      
    }

    const referencias = await database("referencias")
      .join(
        "tipo_produto",
        "tipo_produto.id_tipo_produto",
        "=",
        "referencias.tipo_de_registro"
      )
      .join(
        "produtos_clientes",
        "produtos_clientes.id_produto",
        "=",
        "referencias.indicador_produto_id"
      )
      // .join("tipo_produto_cliente","tipo_produto_cliente.tipo_registo","=","tipo_produto.id_tipo_produto")
      .where({ num_referencia })
      .andWhere({ entidade_cliente: numero_entidade })
      // .andWhere({entidade_cliente: numero_entidade})
      .orWhere({ referencia_do_montante: num_referencia })
      .orderBy("id_referencia", "DESC");
    return { status: "sucesso", mensagem: referencias };
  } catch (error) {
    console.log(error);
    return { status: "erro", mensagem: "Algo aconteceu. Tente de novo!" };
  }
};

module.exports.getReferenciasEntidade = async function (entidade_cliente, pagina, limite) {
  try {

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

    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 referencias = await database('referencias')
      .join("tipo_produto","tipo_produto.id_tipo_produto","=","referencias.tipo_de_registro")      
      .join("produtos_clientes","produtos_clientes.id_produto","=","referencias.indicador_produto_id")
      .where({entidade_cliente: entidade_cliente})
      .orderBy('id_referencia','DESC')

      const numero_registros = referencias.length;
      const registroPorPagina =  +limite || 100
      let  pagina_actual = +pagina  || 1;
      let total_paginas = Math.ceil(numero_registros/registroPorPagina); 
      
      if(pagina_actual == "0") pagina_actual = 1;
      if(registroPorPagina == "0") registroPorPagina = 100;
      
      let count = (pagina_actual * registroPorPagina) - registroPorPagina;
      
      const referenciasLimite = await database('referencias')
      .join("tipo_produto","tipo_produto.id_tipo_produto","=","referencias.tipo_de_registro")      
      .join("produtos_clientes","produtos_clientes.id_produto","=","referencias.indicador_produto_id")
      .where({entidade_cliente: entidade_cliente})
      .limit(registroPorPagina)
      .offset(count)
      .orderBy('id_referencia','DESC')
      
      return {status: "sucesso", registros: {paginas: total_paginas, pagina_actual, total: numero_registros, total_apresentados: referenciasLimite.length, limite: registroPorPagina}, mensagem: referenciasLimite}
 
  } catch (error) {
    console.log(error);
    return { status: "erro", mensagem: "Algo aconteceu. Tente de novo!" };
  }
};

module.exports.getReferenciasEntidadeGrupoAfiliados = async function (entidade_cliente, grupo_identificacao, pagina, limite) {
  try {

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

    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 referencias = await database('referencias')
      .join(
        "tipo_produto",
        "tipo_produto.id_tipo_produto",
        "=",
        "referencias.tipo_de_registro"
      )
      .join(
        "produtos_clientes",
        "produtos_clientes.id_produto",
        "=",
        "referencias.indicador_produto_id"
      )
      .join("afiliados","afiliados.id_afiliado","=","referencias.gerado_por_afiliado")
      .join(
        "identificacao_afiliados",
        "identificacao_afiliados.id_identificacao_afiliados",
        "=",
        "afiliados.grupo_identificacao"
      )
      .where({ entidade_cliente })
      .andWhere({ grupo_identificacao })
      .orderBy('id_referencia','DESC')

      const numero_registros = referencias.length;
      const registroPorPagina =  +limite || 100
      let  pagina_actual = +pagina  || 1;
      let total_paginas = Math.ceil(numero_registros/registroPorPagina); 
      
      if(pagina_actual == "0") pagina_actual = 1;
      if(registroPorPagina == "0") registroPorPagina = 100;
      
      let count = (pagina_actual * registroPorPagina) - registroPorPagina;
      
      const referenciasLimite = await database('referencias')
      .join(
        "tipo_produto",
        "tipo_produto.id_tipo_produto",
        "=",
        "referencias.tipo_de_registro"
      )
      .join(
        "produtos_clientes",
        "produtos_clientes.id_produto",
        "=",
        "referencias.indicador_produto_id"
      )
      .join("afiliados","afiliados.id_afiliado","=","referencias.gerado_por_afiliado")
      .join(
        "identificacao_afiliados",
        "identificacao_afiliados.id_identificacao_afiliados",
        "=",
        "afiliados.grupo_identificacao"
      )
      .where({ entidade_cliente })
      .andWhere({ grupo_identificacao })
      .limit(registroPorPagina)
      .offset(count)
      .orderBy('id_referencia','DESC')
      
      return {status: "sucesso", registros: {paginas: total_paginas, pagina_actual, total: numero_registros, total_apresentados: referenciasLimite.length, limite: registroPorPagina}, mensagem: referenciasLimite}
 
  } catch (error) {
    console.log(error);
    return { status: "erro", mensagem: "Algo aconteceu. Tente de novo!" };
  }
};

module.exports.getReferenciasDias = async function (dia_inicio, dia_final, pagina, limite) {
  try {
    const referencias = await database("referencias")
      .join(
        "tipo_produto",
        "tipo_produto.id_tipo_produto",
        "=",
        "referencias.tipo_de_registro"
      )
      .join(
        "produtos_clientes",
        "produtos_clientes.id_produto",
        "=",
        "referencias.indicador_produto_id"
      )
      // .join("tipo_produto_cliente","tipo_produto_cliente.tipo_registo","=","tipo_produto.id_tipo_produto")
      .whereBetween("criada_r", [dia_inicio, dia_final])
      .orderBy("id_referencia", "DESC");
      

    const numero_registros = referencias.length;
      const registroPorPagina =  +limite || 100
      let  pagina_actual = +pagina  || 1;
      let total_paginas = Math.ceil(numero_registros/registroPorPagina); 
      
      if(pagina_actual == "0") pagina_actual = 1;
      if(registroPorPagina == "0") registroPorPagina = 100;
      
      let count = (pagina_actual * registroPorPagina) - registroPorPagina;
      
      const referenciasLimite = await database('referencias')
      .join(
        "tipo_produto",
        "tipo_produto.id_tipo_produto",
        "=",
        "referencias.tipo_de_registro"
      )
      .join(
        "produtos_clientes",
        "produtos_clientes.id_produto",
        "=",
        "referencias.indicador_produto_id"
      )
      // .join("tipo_produto_cliente","tipo_produto_cliente.tipo_registo","=","tipo_produto.id_tipo_produto")
      .whereBetween("criada_r", [dia_inicio, dia_final])
      .limit(registroPorPagina)
      .offset(count)
      .orderBy('id_referencia','DESC')
      
      
      return {status: "sucesso", registros: {paginas: total_paginas, pagina_actual, total: numero_registros, total_apresentados: referenciasLimite.length, limite: registroPorPagina}, mensagem: referenciasLimite}
    
  } catch (error) {
    console.log(error);
    return { status: "erro", mensagem: "Algo aconteceu. Tente de novo!" };
  }
};

module.exports.getReferenciasEntidadeDias = async function (
  entidade_cliente,
  dia_inicio,
  dia_final,
  pagina, limite
) {
  try {
    const referencias = await database("referencias")
      .join(
        "tipo_produto",
        "tipo_produto.id_tipo_produto",
        "=",
        "referencias.tipo_de_registro"
      )
      .join(
        "produtos_clientes",
        "produtos_clientes.id_produto",
        "=",
        "referencias.indicador_produto_id"
      )
      // .join("tipo_produto_cliente","tipo_produto_cliente.tipo_registo","=","tipo_produto.id_tipo_produto")
      .whereBetween("criada_r", [dia_inicio, dia_final])
      .andWhere({ entidade_cliente })
      .orderBy("id_referencia", "DESC");
    
      const numero_registros = referencias.length;
      const registroPorPagina =  +limite || 100
      let  pagina_actual = +pagina  || 1;
      let total_paginas = Math.ceil(numero_registros/registroPorPagina); 
      
      if(pagina_actual == "0") pagina_actual = 1;
      if(registroPorPagina == "0") registroPorPagina = 100;
      
      let count = (pagina_actual * registroPorPagina) - registroPorPagina;
      
      const referenciasLimite = await database('referencias')
      .join(
        "tipo_produto",
        "tipo_produto.id_tipo_produto",
        "=",
        "referencias.tipo_de_registro"
      )
      .join(
        "produtos_clientes",
        "produtos_clientes.id_produto",
        "=",
        "referencias.indicador_produto_id"
      )
      // .join("tipo_produto_cliente","tipo_produto_cliente.tipo_registo","=","tipo_produto.id_tipo_produto")
      .whereBetween("criada_r", [dia_inicio, dia_final])
      .limit(registroPorPagina)
      .offset(count)
      .orderBy('id_referencia','DESC')
      
      
      return {status: "sucesso", registros: {paginas: total_paginas, pagina_actual, total: numero_registros, total_apresentados: referenciasLimite.length, limite: registroPorPagina}, mensagem: referenciasLimite}
    

  } catch (error) {
    console.log(error);
    return { status: "erro", mensagem: "Algo aconteceu. Tente de novo!" };
  }
};

module.exports.importarXML = async function(entidade, id_clientes, dados, req) {
  try {
    
    

    var sucesso = 0;
    var erros = 0;

    const refSucesso = []
    const refErro = []

    const promessa = new Promise((resolve, reject) => {
      
      parseString(dados, async function (err, result) {
      const Datas = result.Workbook.Worksheet[0].Table[0].Row

      const referencias = [];
      const overData = {}

      if(Datas.length < 2){
        return {status: "erro", mensagem: "Não foi possivel interpretar sua importação! verique as linhas ou os campos"}
      }

      if(Datas.length){

          for (let index = 0; index < Datas.length; index++) {

            if(index == 0) continue;

            
            if(Datas[index].Cell.length > 0){

                for (let index2 = 0; index2 < Datas[index].Cell.length; index2++) {
                    overData[Datas[0].Cell[index2].Data[0]._] = Datas[index].Cell[index2].Data[0]._                  
                }

                const produtos_clientes = await database("produtos_clientes")
                .join("tipo_produto_cliente", "tipo_produto_cliente.id_tipo_produto_clientes", "=", "produtos_clientes.cliente_tipo_produto")
                .join("clientes", "clientes.id_clientes", "=", "tipo_produto_cliente.cliente")
                .join("tipo_produto", "tipo_produto.id_tipo_produto", "=", "tipo_produto_cliente.tipo_registo")
                .orderBy("id_produto", "DESC")
                .where({ numero_entidade: entidade})
                .andWhere({ id_clientes: id_clientes});

                if(produtos_clientes.length){

                    if(produtos_clientes[0].id_tipo_produto == 3){
                      overData["montante_minimo"] = ref.montante_da_factura
                      overData["montante_maximo"] = ref.montante_da_factura
          
                      delete ref.montante_da_factura
                    }
          
                    overData["tipo_de_registro"] = produtos_clientes[0].id_tipo_produto
                    overData["codigo_de_processamento"] = 80
                    overData["indicador_de_produtos"] = produtos_clientes[0].codigo_do_produto
                    overData["indicador_produto_id"] = produtos_clientes[0].id_produto
                    overData["entidade_cliente"] = entidade
                }

                const ref = overData
                referencias.push(ref)
                const rs = await REF.postReferenciaImport({...req, body: overData})
   

                if(rs.status == "sucesso") {
                  refSucesso.push(overData)
                  sucesso++;
                }
                else {
                  refErro.push(overData)
                  erros++;
                }

              }
                          
          }
      }

      resolve({sucesso, erros})
      
    })
  })

    console.log(await promessa)

    console.log({sucesso: refSucesso.length , erros: refErro.length, total: sucesso+erros})
    return {status: "sucesso", mensagem: {sucesso , erros, total: sucesso+erros}} 
     

  } catch (erro) {
    console.log(erro)
    return {status:'erro', mensagem: 'Algo aconteceu. Tente de novo'}
  }
    
}

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

  
  try {

    const referencias =  await database('referencias')
    .where({entidade_cliente: dados.entidade_cliente})
    .andWhere('num_referencia', 'LIKE', `%${dados.num_referencia}%`, 'OR', 'IS null')
    .andWhere('data_limite_pagamento','LIKE', `%${dados.data_limite_pagamento}%`, 'OR', 'data_limite_pagamento' ,'IS null')
    .andWhere('indicador_produto_id', 'LIKE', `%${dados.indicador_produto_id}%`, 'OR', 'indicador_produto_id' ,'IS null')
    .andWhere('indicador_de_produtos', 'LIKE', `%${dados.indicador_de_produtos}%`, 'OR', 'indicador_de_produtos' ,'IS null')
    .andWhere('tipo_de_registro', 'LIKE', `%${dados.tipo_de_registro}%`, 'OR', 'tipo_de_registro' ,'IS null')
    // .whereNull('montante_fixo', 'LIKE', `%${dados.montante_fixo}%`, 'OR', 'montante_fixo', 'IS null')
    .andWhere('codigo_de_processamento', 'LIKE', `%${dados.codigo_de_processamento}%`, 'OR', 'codigo_de_processamento', 'IS null')
    // .whereNull('opcional_1', 'LIKE', `%${dados.opcional_1}%`, 'OR', 'indicador_de_produtos' ,'IS null')
    // .whereNull('opcional_2', 'LIKE', `%${dados.opcional_2}%`, 'OR', 'indicador_de_produtos' ,'IS null')
    // .whereNull('opcional_3', 'LIKE', `%${dados.opcional_3}%`, 'OR', 'indicador_de_produtos' ,'IS null')
    .whereNull('data_inicio_de_pagamento', 'LIKE', `%${dados.data_inicio_de_pagamento}%`, 'OR', 'IS NULL')
    // .whereNull('montante_minimo', 'LIKE', `%${dados.montante_minimo}%`, 'OR','montante_minimo', 'IS NULL')
    // .whereNull('montante_maximo', 'LIKE', `%${dados.montante_maximo}%`, 'OR','montante_maximo', 'IS NULL')
    // .whereNull('codigo_de_cliente', 'LIKE', `%${dados.codigo_de_cliente}%`, 'OR','codigo_de_cliente','IS NULL')
    // .whereNull('numero_de_linhas', 'LIKE', `%${dados.numero_de_linhas}%`, 'OR', 'numero_de_linhas','IS NULL')
    // .whereNull('textos_para_talao', 'LIKE', `%${dados.textos_para_talao}%`, 'OR','textos_para_talao', 'IS NULL')
    .orderBy('id_referencia','desc')
    
    const numero_registros = referencias.length;
      const registroPorPagina =  +limite || 100
      let  pagina_actual = +pagina  || 1;
      let total_paginas = Math.ceil(numero_registros/registroPorPagina); 
      
      if(pagina_actual == "0") pagina_actual = 1;
      if(registroPorPagina == "0") registroPorPagina = 100;
      
      let count = (pagina_actual * registroPorPagina) - registroPorPagina;

      const referenciasLimite = await database('referencias')
      .where({entidade_cliente: dados.entidade_cliente})
      .andWhere('num_referencia', 'LIKE', `%${dados.num_referencia}%`, 'OR', 'IS null')
      .andWhere('data_limite_pagamento','LIKE', `%${dados.data_limite_pagamento}%`, 'OR', 'data_limite_pagamento' ,'IS null')
      .andWhere('indicador_produto_id', 'LIKE', `%${dados.indicador_produto_id}%`, 'OR', 'indicador_produto_id' ,'IS null')
      .andWhere('indicador_de_produtos', 'LIKE', `%${dados.indicador_de_produtos}%`, 'OR', 'indicador_de_produtos' ,'IS null')
      .andWhere('tipo_de_registro', 'LIKE', `%${dados.tipo_de_registro}%`, 'OR', 'tipo_de_registro' ,'IS null')
      // .whereNull('montante_fixo', 'LIKE', `%${dados.montante_fixo}%`, 'OR', 'montante_fixo', 'IS null')
      .andWhere('codigo_de_processamento', 'LIKE', `%${dados.codigo_de_processamento}%`, 'OR', 'codigo_de_processamento', 'IS null')
      // .whereNull('opcional_1', 'LIKE', `%${dados.opcional_1}%`, 'OR', 'indicador_de_produtos' ,'IS null')
      // .whereNull('opcional_2', 'LIKE', `%${dados.opcional_2}%`, 'OR', 'indicador_de_produtos' ,'IS null')
      // .whereNull('opcional_3', 'LIKE', `%${dados.opcional_3}%`, 'OR', 'indicador_de_produtos' ,'IS null')
      .whereNull('data_inicio_de_pagamento', 'LIKE', `%${dados.data_inicio_de_pagamento}%`, 'OR', 'IS NULL')
      // .whereNull('montante_minimo', 'LIKE', `%${dados.montante_minimo}%`, 'OR','montante_minimo', 'IS NULL')
      // .whereNull('montante_maximo', 'LIKE', `%${dados.montante_maximo}%`, 'OR','montante_maximo', 'IS NULL')
      // .whereNull('codigo_de_cliente', 'LIKE', `%${dados.codigo_de_cliente}%`, 'OR','codigo_de_cliente','IS NULL')
      // .whereNull('numero_de_linhas', 'LIKE', `%${dados.numero_de_linhas}%`, 'OR', 'numero_de_linhas','IS NULL')
      // .whereNull('textos_para_talao', 'LIKE', `%${dados.textos_para_talao}%`, 'OR','textos_para_talao', 'IS NULL')
      // .whereNull('textos_para_talao', 'LIKE', `%${dados.textos_para_talao}%`, 'OR','textos_para_talao', 'IS NULL')
      .limit(registroPorPagina)
      .offset(count)
      .orderBy('id_referencia','desc')

    
        return {status:"sucesso", registros: {paginas: total_paginas, pagina_actual, total: numero_registros, total_apresentados: referenciasLimite.length, limite: registroPorPagina}, mensagem:referenciasLimite}
      
      
    
  } catch (error) {
    console.error(error.message);
    return { status: "erro", mensagem: "Algo aconteceu. tente de novo" };
  }
};

module.exports.postReferencia = async function (dados, req) {

  
  
  try {

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

      let tipo_referencia_pagamento = 'P'
      let aceitar_fixo = "NÃO"

      const produtos_clientes = await database('valores_fixos')
      .where({produto_cliente: dados.indicador_produto_id})
      .andWhere({entidade_produdo: dados.entidade_cliente})
      

      if(produtos_clientes.length > 0) tipo_referencia_pagamento = 'L'



      if(dados.tipo_de_registro == 2) tipo_referencia_pagamento = 'R'
      if(dados.tipo_de_registro == 3) tipo_referencia_pagamento = 'I'
        

      if((verifivarPagamentoTempoReal[0]?.servico_pagamento_por_sector == "false") && (verifivarPagamentoTempoReal[0]?.servico_gpo == "false")){
        return {status:"erro", mensagem:`Serviço de pagamento inactivo`}      
      }

      
    const entidade = await database("clientes").where({
      numero_entidade: dados.entidade_cliente
    });

    
      
    if(tipo_referencia_pagamento == "P"){
          if(dados.montante_fixo && (dados.montante_fixo > 10))
            aceitar_fixo = "SIM"
          
          if(dados.montante_limitado_para_pagamento_longo && (dados.montante_limitado_para_pagamento_longo > 10))
            dados.montante_limitado_para_pagamento_longo = dados.montante_limitado_para_pagamento_longo
          else
            dados.montante_limitado_para_pagamento_longo = 0
    }
      

    if (entidade.length == 0)
      return { status: "erro", mensagem: "Entidade invalida" };

    if(dados.tipo_de_registro == "3"){
      dados.montante_minimo = String(dados.montante_minimo).substr(-2) == "00" ? dados.montante_minimo + ".00" : dados.montante_minimo
      dados.montante_maximo = String(dados.montante_maximo).substr(-2) == "00" ? dados.montante_maximo + ".00" : dados.montante_maximo
    }

    if (dados.tipo_de_registro == "1" || dados.tipo_de_registro == "3") {
      

      if (dados?.num_referencia.toString().length != entidade[0].num_padrao_referencias){

        if(entidade[0].preenchimento_refs_zeros_a_esquerda == "SIM"){

          if (dados?.num_referencia.toString().length < Number(entidade[0].num_padrao_referencias)){
            const quantidadeCaracter = dados?.num_referencia.length
            const repeatCaracter = "0".repeat(Number(entidade[0].num_padrao_referencias) - Number(quantidadeCaracter))
            dados.num_referencia = repeatCaracter.concat(dados?.num_referencia)
          }else{
              return {
                status: "erro",
                mensagem: "Número de caracteres para gerar referência invalido!"
              }
          }
        }else{

          return {
            status: "erro",
            mensagem: "Número de caracteres para gerar referência invalido!"
          }

        }

      }

      const clientesRef = await database("referencias")
        .where({ entidade_cliente: dados.entidade_cliente })
        .andWhere({ num_referencia: dados?.num_referencia })
        .andWhere({ tipo_de_registro: dados.tipo_de_registro });

      if(entidade[0].versao_mensagem_PRT == "05"){
    
        if(verifivarPagamentoTempoReal[0].pagamento_tempo_real == "true"){
  
          if((dados?.nib != '0') && (dados?.nib.length == 21)){
                dados = {...dados, nib: dados.nib}
          }else{
  
            return {status: "erro", mensagem: "Entidade não tem parametrização de versão de mensagem para pagementos Real Time a serem validados o NIB ou IBAN"}
  
          }
  
        }
  
      }

      if (clientesRef.length > 0)
        return {
          status: "erro",
          mensagem: "Referência já existente! Escolhe outra"
        };

      if (
        (dados?.num_referencia.toString().length != entidade[0].num_padrao_referencias) &&
        (dados.tipo_de_registro == "3")
      )
        return {
          status: "erro",
          mensagem: "Número de caracteres para gerar referência invalido!"
        };
    } else if (dados.tipo_de_registro == "2") {
      const clientesRef2 = await database("referencias")
        .where({ entidade_cliente: dados.entidade_cliente })
        .andWhere({ referencia_do_montante: dados?.referencia_do_montante })
        .andWhere({ tipo_de_registro: dados.tipo_de_registro });
      if (dados?.referencia_do_montante.toString().length != 5) 
        return {
          status: "erro",
          mensagem: "Número de caracteres para gerar referência invalido!"
        };
      if (clientesRef2.length > 0)
        return {
          status: "erro",
          mensagem: "Referência já existente! Escolhe outra"
        };
    }

    const smsConf = await database('configuracoes').where({cliente_entidade: dados.entidade_cliente})
    let notification = null
    if(smsConf[0].servico_mensagens == "true"){
      const sms = await database('envio_config_mensagem').where({env_entidade: dados.entidade_cliente}).andWhere({tipo_env: "referencias"})

      if(sms.length){
        const mensagem = sms[0].mensagem
        notification = {efeito: {...dados}, para:"REFERENCIAS", mensagem, canal:"sms"}
      }       

    } 
    
    if(dados.codigo_de_processamento == "80"){

      let mft = null

      let entidade_master = entidade[0].entidade_master
      if(dados.tipo_de_registro == "3"){
          mft = {entidade: dados.entidade_cliente, entidade_master, refs: [{...dados}], encaminhar: 'SIM'}

          delete dados?.montante_limitado_para_pagamento_longo_pago

          await database("referencias").insert({...dados, tipo_referencia_pagamento, estado_atm: 'Inactivo', aceitar_fixo});

      }else{

        const entidadeMFT = await database('clientes').where({numero_entidade: dados.entidade_cliente})
        if(entidadeMFT[0].validacao_referencias == "Ficheiros"){
          mft = {entidade: dados.entidade_cliente, refs: [{...dados}], encaminhar: 'SIM'}
        }
          delete dados?.montante_limitado_para_pagamento_longo_pago

          await database("referencias").insert({...dados, tipo_referencia_pagamento, aceitar_fixo});
      }
      
      if(smsConf[0].servico_email == "true"){
        const [clientesValidado] = await database("referencias")
        .join("clientes","clientes.numero_entidade","=","referencias.entidade_cliente")
        .where({ entidade_cliente: dados.entidade_cliente })
        .andWhere({ num_referencia: dados?.num_referencia })
        .andWhere({ tipo_de_registro: dados.tipo_de_registro });
          
        if(clientesValidado.opcional_2){
          if(notification){
            const email = clientesValidado.opcional_2 ? clientesValidado.opcional_2.split("=")[1] : 'noreply@intelize.ao';
            const nome_cliente = clientesValidado.opcional_1 ? clientesValidado.opcional_1.split("=")[1] : 'Intelize investimentos';
            notification = {...notification, modo:"envioReferencia"}
            notification.opcional = "email"
            notification.informacao = {...clientesValidado, email, nome_cliente}
          }else{
            const email = clientesValidado.opcional_2 ? clientesValidado.opcional_2.split("=")[1] : 'noreply@intelize.ao';
            const nome_cliente = clientesValidado.opcional_1 ? clientesValidado.opcional_1.split("=")[1] : 'Intelize investimentos';
            notification = {efeito: {...clientesValidado, email, nome_cliente}, para:"envioReferencia", mensagem: 'alguma coisa', canal:"email"}
          }
        }
      }
      
      return { 
        webhook: {id_evento: 1, entidade: dados.entidade_cliente, info:{ ...dados }},
        status: "sucesso", 
        mft,
        mensagem: "Referecia gerada com sucesso" ,
        notification,
        logs: {ip: req.ip, verbo_rota_API: req.method, rota_API: req.originalUrl, tipo: "ACTIVEREFERENCIAS" , tabela: "REFERENCIAS", informacao: dados, entidade: dados.entidade_cliente}
      }
    }    
    else if(dados.codigo_de_processamento == "82"){
  
      delete dados?.montante_limitado_para_pagamento_longo_pago

      await database("referencias").insert({...dados, estado_atm: 'Inactivo', aceitar_fixo});
      
      let mft = null
      let entidade_master = entidade[0].entidade_master

      if(dados.tipo_de_registro == "3"){
          mft = {entidade: dados.entidade_cliente, entidade_master, refs: [{...dados}], encaminhar: 'SIM'}
      }else{

        const entidadeMFT = await database('clientes').where({numero_entidade: dados.entidade_cliente})
        if(entidadeMFT[0].validacao_referencias == "Ficheiros"){
          mft = {entidade: dados.entidade_cliente, refs: [{...dados}], encaminhar: 'SIM'}
        }
      }

      if(smsConf[0].servico_email == "true"){
        const [clientesValidado] = await database("referencias")
        .join("clientes","clientes.numero_entidade","=","referencias.entidade_cliente")
        .where({ entidade_cliente: dados.entidade_cliente })
        .andWhere({ num_referencia: dados?.num_referencia })
        .andWhere({ tipo_de_registro: dados.tipo_de_registro });
        
        if(clientesValidado.opcional_2){
          if(notification){
            const email = clientesValidado.opcional_2 ? clientesValidado.opcional_2.split("=")[1] : 'noreply@intelize.ao';
            const nome_cliente = clientesValidado.opcional_1 ? clientesValidado.opcional_1.split("=")[1] : 'Intelize investimentos';
            notification = {...notification, modo:"envioReferencia"}
            notification.opcional = "email"
            notification.informacao = {...clientesValidado, email, nome_cliente}
          }else{
            const email = clientesValidado.opcional_2 ? clientesValidado.opcional_2.split("=")[1] : 'noreply@intelize.ao';
            const nome_cliente = clientesValidado.opcional_1 ? clientesValidado.opcional_1.split("=")[1] : 'Intelize investimentos';
            notification = {efeito: {...clientesValidado, email, nome_cliente}, para:"envioReferencia", mensagem: 'alguma coisa', canal:"email"}
          }
        }
      }
  
      return { 
        webhook: {id_evento: 1, entidade: dados.entidade_cliente, info:{ ...dados }},
        status: "sucesso", 
        mft,
        mensagem: "Referecia gerada com sucesso" ,
        notification,
        logs: {ip: req.ip, verbo_rota_API: req.method, rota_API: req.originalUrl, tipo: "DESACTIVEREFERENCIAS" , tabela: "REFERENCIAS", informacao: dados, entidade: dados.entidade_cliente}
      }
      
    }
    else{
      return { status: "erro", mensagem: "Codigo de processamento invalido" };
    }
    
    
  } catch (error) {
    console.error(error.message);
    return { status: "erro", mensagem: "Algo aconteceu. tente de novo" };
  }
};

module.exports.patchReferencia = async function (id_referencia, dados, req) {
  try {
    const actualiza_em = new Date()
      .toISOString()
      .replace("T", " ")
      .substr(0, 19);

    
      if(dados?.opcional_1){
        if(!/[a-zA-Z]{2,}=[\w{2,}\.\-\,\d\s]{1,}/ig.test(dados?.opcional_1))
          return {
            status: "erro",
            mensagem: "Deve colocar correctamente dos dados (CAMPO 1). EX: campo=valor"
          }
      }
  
      if(dados?.opcional_2){
        if(!/[a-zA-Z]{2,}=[\w{2,}\.\-\,\d\s]{1,}/ig.test(dados?.opcional_2))
          return {
            status: "erro",
            mensagem: "Deve colocar correctamente dos dados (CAMPO 1). EX: campo=valor"
          }
      }
  
      if(dados?.opcional_3){
        if(!/[a-zA-Z]{2,}=[\w{2,}\.\-\,\d\s]{1,}/ig.test(dados?.opcional_3))
          return {
            status: "erro",
            mensagem: "Deve colocar correctamente dos dados (CAMPO 1). EX: campo=valor"
          }
      }
      

    const refBefore = await database("referencias").where({ id_referencia });
    const refNew = refBefore[0]

    if(dados.tipo_de_registro == "3"){
      dados.montante_minimo = String(dados.montante_minimo).substr(-2) == "00" ? dados.montante_minimo + ".00" : dados.montante_minimo
      dados.montante_maximo = String(dados.montante_maximo).substr(-2) == "00" ? dados.montante_maximo + ".00" : dados.montante_maximo
    }
    
    delete dados.entidade_cliente
    delete dados.tipo_de_registro


    let aceitar_fixo =  "NÃO"
    
    if((dados?.num_referencia) || (dados?.referencia_do_montante)){
      const verifyRef = await database("referencias")
      .where({ entidade_cliente: refNew.entidade_cliente })
      .andWhere({ num_referencia: dados?.num_referencia })
      // .orWhere({referencia_do_montante : dados?.referencia_do_montante})

      if(verifyRef[0].tipo_referencia_pagamento == "P"){

        if(Number(dados?.montante_fixo) > 99){
          aceitar_fixo =  "SIM"
        }

      }
      
      if((verifyRef.length > 0) && (verifyRef[0].id_referencia == id_referencia) && (verifyRef[0].actualiza_em == actualiza_em))  return { status: "erro", mensagem: "Referência á actualizar já existente" };
    }
    

    let estado_atm =  "Activo"

    if(dados?.codigo_de_processamento) {
        estado_atm = dados.codigo_de_processamento == "80" ? "Activo" : "Inactivo"
    }

    if(dados?.num_referencia) delete dados.num_referencia

    if(dados?.montante_limitado_para_pagamento_longo_pago) delete dados?.montante_limitado_para_pagamento_longo_pago
    
    await database("referencias")
      .where({ id_referencia })
      .update({ ...dados, actualiza_em, estado_atm, aceitar_fixo });

    const refAfter = await database("referencias").where({ id_referencia });
    const refNew_ = refAfter[0]

    let mft = null

    if(refNew_.tipo_de_registro == "3"){
      mft = {entidade: refNew_.entidade_cliente, refs: [{...dados, ...refNew_}], encaminhar: 'SIM'}
    }
    

    return { 
      webhook: {id_evento: 2, entidade: refNew.entidade_cliente, info:{ antes: refNew, depois: refNew_}},
      status: "sucesso", 
      mft,
      mensagem: "Referecia actualizada com sucesso" ,
      logs: {ip: req.ip, verbo_rota_API: req.method, rota_API: req.originalUrl, tipo: "PATCH" , tabela: "REFERENCIAS", informacao: {...dados, id_referencia}, entidade: refNew_.entidade_cliente}
    }
  } catch (error) {
    console.error(error.message);
    return { status: "erro", mensagem: "Algo aconteceu. tente de novo" };
  }
};

module.exports.deleteReferencia = async function (id_referencia, req) {
  try {
    const ref = await database("referencias").where({ id_referencia }); 

    const refComPagamento = await database("referencias")
    .join("pagamentos","referencias.num_referencia","=","pagamentos.referencia_do_servico")
    .where({ id_referencia }); 

    if(refComPagamento.length > 0) {
      return { status: "erro", mensagem: "Não pode deletar essa referência no momento, Tem associação de pagamentos" };
    }
    
    if((ref[0].estado_atm == "Á Processar") || (ref[0].estado_atm == "Activo"))
    return { status: "erro", mensagem: "Não pode deletar essa referência no momento, Está em activação ou processamento" };
    
    await database("referencias").where({ id_referencia }).del();

    let mft = null

    if(ref[0].tipo_de_registro == "3"){
      mft = {entidade: ref[0].entidade_cliente, refs: [{...ref[0], codigo_de_processamento: "82"}], encaminhar: 'SIM'}
    }

    return { 
      webhook: {id_evento: 3, entidade: ref[0].entidade_cliente, info: { ...ref[0] }},
      status: "sucesso", 
      mft,
      mensagem: "Referecia excluida com sucesso" ,
      logs: {ip: req.ip, verbo_rota_API: req.method, rota_API: req.originalUrl, tipo: "DELETE" , tabela: "REFERENCIAS", informacao: ref[0], entidade: ref[0].entidade_cliente}
    }
  } catch (error) {
    console.error(error.message);
    return { status: "erro", mensagem: "Algo aconteceu. tente de novo" };
  }
};
