const database = require("../config/database");
const response = require("../constants/response");
const logger = require('../services/loggerService');
const {perfilFilteres, afiliadosFilteres, pagamentosFilteres, clientesFilteres} = require("../helpers/filterResponseSQL")
const calculateTransations = require("../helpers/calculateTransations")

module.exports.getDashboardTodos = async function (req) {
  try {
    
      logger("SERVIDOR:Clientes").debug("Selecionar da base de dados")
      const perfil = await database("clientes")

      logger("SERVIDOR:Clientes").debug("Selecionar da base de dados")
      const referenciasGeradas = await database('referencias')

      logger("SERVIDOR:Clientes").debug("Selecionar da base de dados")
      const referenciasInactivas = await database('referencias')
      .andWhereNot({ estado_atm: "Activo" })

      const somatorioMensais = {
        quantidade: [],
        soma: []
      };

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

      logger("SERVIDOR:getDashboard").debug("Loop dos pagamentos mensais no ano corrente para o grafico")
      for (let index = 1; index <= 12; index++) {

        const mes = index.toString().length == 1 ? "0".concat(index.toString()) : index.toString()
                      
        const pagamentoMensal = await database("pagamentos")
        .sum("montante_da_operacao AS soma")
        .count("id_pagamento AS quantidade")
        .whereBetween('data_movimento', [`${anoCorrente}-${mes}-01`, `${anoCorrente}-${mes}-31`])
        .orderBy("id_pagamento", "DESC");

        somatorioMensais.quantidade.push(String(parseInt(pagamentoMensal[0].quantidade)) == "null" ? 0 : parseInt(pagamentoMensal[0].quantidade))
        somatorioMensais.soma.push(String(parseFloat(pagamentoMensal[0].soma)) == "NaN" ? 0 : parseFloat(pagamentoMensal[0].soma.toFixed(2)))

      }

      const somatorioMensaisTabela = [];

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

      logger("SERVIDOR:getDashboard").debug("Loop dos pagamentos mensais no ano corrente para a tabela")
      for (let index = 1; index <= 12; index++) {

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

        const pagamentos = await database('pagamentos')
        .wereBetween('data_movimento', [`${anoCorrenteTabela}-${mes}-01`, `${anoCorrenteTabela}-${mes}-31`])
        .orderBy('id_pagamento','desc')

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


        const filteredPagamentos = pagamentosFilteres(pagamentos)
        const filteredCliente = clientesFilteres(clientes)


        await calculateTransations(somatorioMensaisTabela, anoCorrenteTabela, mes, filteredCliente, filteredPagamentos)   
      
      }

      logger("SERVIDOR:getDashboard").debug("Selecionar todos os pagamentos de hoje")
      const [data_hoje] = new Date().toJSON().split('T')
      const [pagamentosHoje] = await database("pagamentos")
      .sum("montante_da_operacao AS montante_diario")
      .count("id_pagamento AS movimentos")
      .where({ data_movimento: data_hoje })
      .orderBy("id_pagamento", "DESC");

      logger("SERVIDOR:getDashboard").debug("Selecionar os 10 ultimos pagamentos")
      const ultimosPagamentos = await database("pagamentos")
      .limit(10)
      .orderBy("id_pagamento", "DESC");

      logger("SERVIDOR:getDashboard").debug("Selecionar os 10 ultimos periodos")
      const ultimosPeriodos = await database("pagamentos")
      .distinct("Identificacao_Log_EGR AS periodo")
      .sum("montante_da_operacao AS somatorio")
      .count("id_pagamento AS quantidade")
      .max("data_movimento AS data_periodo")
      .limit(10)
      .groupBy(["Identificacao_Log_EGR"])
      .orderBy("Identificacao_Log_EGR", "desc");
      
      logger("SERVIDOR:getDashboard").debug("Selecionar todos afiliados")
      const perfilAfiliados = await database("clientes")
      .join("afiliados", "clientes.id_clientes", "=", "afiliados.cliente_id")
      .join("identificacao_afiliados", "identificacao_afiliados.id_identificacao_afiliados", "=", "afiliados.grupo_identificacao")

      logger("SERVIDOR:getDashboard").debug("Selecionar e ver as configurações")
      const perfilConfiguracao = await database("configuracoes")

      const [filteredCliente] = perfilFilteres(perfil)
      const filteredPagamentos = pagamentosFilteres(ultimosPagamentos)
      const [filteredConfiguracao] = perfilFilteres(perfilConfiguracao)
      const filteredAfiliados = afiliadosFilteres(perfilAfiliados)
      
      filteredCliente.resumo = {
        referencias_geradas: referenciasGeradas.length,
        referencias_inactivas: referenciasInactivas.length,
        pagamentos_diario: {
          ...pagamentosHoje,
          data_hoje
        },
        periodo_activo:{
            periodo: ultimosPeriodos[0] ? ultimosPeriodos[0].periodo : 0,
            montante: ultimosPeriodos[0] ? ultimosPeriodos[0].somatorio : 0
        },
        ultimos_pagamentos: filteredPagamentos,
        ultimos_periodos: ultimosPeriodos,
        dados_mensais: somatorioMensais,
        tabela_mensais: somatorioMensaisTabela
      }
      filteredCliente.configuracao = filteredConfiguracao
      filteredCliente.afiliados = filteredAfiliados

      logger("SERVIDOR:getDashboard").info("Respondendo a requisição")
      const rs = response("sucesso", 200, filteredCliente, "json",
        {
          url: req.originalUrl
        });        
      return rs
    
  } catch (error) {
      console.log(error);
      logger("SERVIDOR:getDashboard").error(`Erro ao buscar clientes ${error.message}`)
      const rs = response("erro", 400, 'Algo aconteceu. Tente de novo');
      return rs
  }
};

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

      logger("SERVIDOR:getDashboard").debug("Selecionar as configurações do cliente")    
      if(!entidade){
        const rs = response("erro", 423, "Valor da entidade inacessivel");
        return rs 
      }

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

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

      logger("SERVIDOR:getDashboard").debug("Selecionar dados do cliente")
      const perfil = await database("clientes")
      .where({numero_entidade: entidade})

      logger("SERVIDOR:getDashboard").debug("Selecionar as referencias do cliente")
      const referenciasGeradas = await database('referencias')
      .where({entidade_cliente: entidade})

      logger("SERVIDOR:getDashboard").debug("Selecionar as referencias não activas do cliente")
      const referenciasInactivas = await database('referencias')
      .where({entidade_cliente: entidade})
      .andWhereNot({ estado_atm: "Activo" })

      const somatorioMensais = {
        quantidade: [],
        soma: []
      };

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

      logger("SERVIDOR:getDashboard").debug("Loop dos pagamentos mensais no ano corrente para o grafico")
      for (let index = 1; index <= 12; index++) {

        const mes = index.toString().length == 1 ? "0".concat(index.toString()) : index.toString()
                      
        const pagamentoMensal = await database("pagamentos")
        .sum("montante_da_operacao AS soma")
        .count("id_pagamento AS quantidade")
        .where({ numero_entidade: entidade })
        .andWhereBetween('data_movimento', [`${anoCorrente}-${mes}-01`, `${anoCorrente}-${mes}-31`])
        .orderBy("id_pagamento", "DESC");
        

        somatorioMensais.quantidade.push(String(parseInt(pagamentoMensal[0].quantidade)) == "null" ? 0 : parseInt(pagamentoMensal[0].quantidade))
        somatorioMensais.soma.push(String(parseFloat(pagamentoMensal[0].soma)) == "NaN" ? 0 : parseFloat(pagamentoMensal[0].soma.toFixed(2)))

      }

     
      const somatorioMensaisTabela = [];

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

      logger("SERVIDOR:getDashboard").debug("Loop dos pagamentos mensais no ano corrente para a tabela")
      for (let index = 1; index <= 12; index++) {

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

        const pagamentos = await database('pagamentos')
        .where({numero_entidade: entidade})
        .whereBetween('data_movimento', [`${anoCorrenteTabela}-${mes}-01`, `${anoCorrenteTabela}-${mes}-31`])
        .orderBy('id_pagamento','desc')

        //const pagamentos = await database.raw(`CALL tabelaMovimentosMensais("${entidade}", "${anoCorrenteTabela}-${mes}-01", "${anoCorrenteTabela}-${mes}-31")`)

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


        const filteredPagamentos = pagamentosFilteres(pagamentos)
        const filteredCliente = clientesFilteres(clientes)


        await calculateTransations(somatorioMensaisTabela, anoCorrenteTabela, mes, filteredCliente, filteredPagamentos)   
      
      }
     

      
      logger("SERVIDOR:getDashboard").debug("Selecionar todos os pagamentos de hoje")
      const [data_hoje] = new Date().toJSON().split('T')
      const [pagamentosHoje] = await database("pagamentos")
      .sum("montante_da_operacao AS montante_diario")
      .count("id_pagamento AS movimentos")
      .where({ numero_entidade: entidade })
      .andWhere({ data_movimento: data_hoje })
      .orderBy("id_pagamento", "DESC");

      logger("SERVIDOR:getDashboard").debug("Selecionar os 10 ultimos pagamentos")
      const ultimosPagamentos = await database("pagamentos")
      .where({ numero_entidade: entidade })
      .limit(10)
      .orderBy("id_pagamento", "DESC");

      logger("SERVIDOR:getDashboard").debug("Selecionar os 10 ultimos periodos")
      const ultimosPeriodos = await database("pagamentos")
      .distinct("Identificacao_Log_EGR AS periodo")
      .sum("montante_da_operacao AS somatorio")
      .count("id_pagamento AS quantidade")
      .max("data_movimento AS data_periodo")
      .limit(10)
      .where({ numero_entidade: entidade })
      .groupBy(["Identificacao_Log_EGR"])
      .orderBy("Identificacao_Log_EGR", "desc");
      
      logger("SERVIDOR:getDashboard").debug("Selecionar todos afiliados")
      const perfilAfiliados = await database("clientes")
      .join("afiliados", "clientes.id_clientes", "=", "afiliados.cliente_id")
      .join("identificacao_afiliados", "identificacao_afiliados.id_identificacao_afiliados", "=", "afiliados.grupo_identificacao")
      .where({numero_entidade: entidade})

      logger("SERVIDOR:getDashboard").debug("Selecionar e ver as configurações")

      const [filteredCliente] = perfilFilteres(perfil)
      const filteredPagamentos = pagamentosFilteres(ultimosPagamentos)
      const [filteredConfiguracao] = perfilFilteres(verifivarPagamentoTempoReal)
      const filteredAfiliados = afiliadosFilteres(perfilAfiliados)
      
      filteredCliente.resumo = {
        referencias_geradas: referenciasGeradas.length,
        referencias_inactivas: referenciasInactivas.length,
        pagamentos_diario: {
          ...pagamentosHoje,
          data_hoje
        },
        periodo_activo:{
            periodo: ultimosPeriodos[0] ? ultimosPeriodos[0].periodo : 0,
            montante: ultimosPeriodos[0] ? ultimosPeriodos[0].somatorio : 0
        },
        ultimos_pagamentos: filteredPagamentos,
        ultimos_periodos: ultimosPeriodos,
        dados_mensais: somatorioMensais,
        tabela_mensais: somatorioMensaisTabela
      }
      filteredCliente.configuracao = filteredConfiguracao
      filteredCliente.afiliados = filteredAfiliados

      logger("SERVIDOR:getDashboard").info("Respondendo a requisição")
      const rs = response("sucesso", 200, filteredCliente, "json",
        {
          url: req.originalUrl
        });         
      return rs
    
  } catch (error) {
      console.log(error);
      logger("SERVIDOR:getDashboard").error(`Erro ao buscar clientes ${error.message}`)
      const rs = response("erro", 400, 'Algo aconteceu. Tente de novo');
      return rs
  }
};
