const models = require('../models/endpoints')
const yup = require('yup')
const {client} = require('../utils/rabbitMQ');
const response = require("../constants/response");
const logger = require('../services/loggerService'); 
const sendRequestOnMicroservices = require("../helpers/sendRequestOnMicroservices");  

module.exports.getEndpoints = async function(req, res, next) {
   
  try {

      const {pagina, limite, total_registros, entidade = '', activo = '', url = ''} = req.query
      const results = await models.getEndpoints(pagina, limite, total_registros, entidade, activo, url)
      res.status(results.statusCode).json(results)
 
  } catch (error) {
      console.error(error.message);
      logger("SERVIDOR:getDashboardTodos").error(`Erro ao buscar o perfil clientes ${error.message}`)
      const rs = response("erro", 400, `Algo aconteceu. Tente de novo, ${error.message}`);
      res.status(rs.statusCode).json(rs)
  }
    
}   

module.exports.getEndpointsID = async function(req, res, next) {
   
  try {

      const {id_endpoint} =  req.params 
      const results = await models.getEndpointsID(id_endpoint)
      res.status(results.statusCode).json(results)

  } catch (error) {
      console.error(error.message);
      logger("SERVIDOR:getDashboardTodos").error(`Erro ao buscar o perfil clientes ${error.message}`)
      const rs = response("erro", 400, `Algo aconteceu. Tente de novo, ${error.message}`);
      res.status(rs.statusCode).json(rs)
  }
    
}  

module.exports.getEndpointsEntidade = async function(req, res, next) {
   
  try {

      const {entidade_aceite} =  req.params 
      const {pagina, limite, total_registros, activo = '', url = ''} = req.query
      const results = await models.getEndpointsEntidade(pagina, limite, total_registros, entidade_aceite, activo, url)
      res.status(results.statusCode).json(results)

  } catch (error) {
      console.error(error.message);
      logger("SERVIDOR:getDashboardTodos").error(`Erro ao buscar o perfil clientes ${error.message}`)
      const rs = response("erro", 400, `Algo aconteceu. Tente de novo, ${error.message}`);
      res.status(rs.statusCode).json(rs)
  }
    
}   

module.exports.postEndpoints = async function(req, res, next) { 
  try {

      logger("SERVIDOR:postClientes").info(`Iniciando cadastrado o cliente`)
      
      const dados =  req.body

      const schemaEndpoints = yup.object().shape({
        url: yup.string().trim().url().required(),
        activo: yup.mixed().oneOf(['true', 'false']).default('true'), 
        evento: yup.number().required().default('8'),
        bearer_token: yup.string(),
        entidade_aceite: yup.string().min(5).required(),
        verificar_ssl: yup.mixed().oneOf(['true', 'false']).default('true'),
        tipo_endpoint: yup.mixed().oneOf(['NORMAL', 'PRIMAVERA','VENDUS']).required(),
        para_servico: yup.mixed().oneOf(['REFERENCIAS', 'GPO']).default('REFERENCIAS').required(),
        gpo_eventos: yup.string().oneOf(['PAID', 'PAID,REJECTD', 'PAID,REFUNDED', 'PAID,REJECTD,REFUNDED', 'REJECTD', 'REJECTD,REFUNDED', 'REFUNDED']).required().default('PAID'),
        campo_codigo_cliente_primavera: yup.mixed().oneOf(['opcional_1','opcional_2','opcional_3']).default('opcional_1'),
        tipo_resposta: yup.mixed().oneOf(['Completa','Resumida','Formatada']).default('Completa'),
        line_primavera: yup.mixed().oneOf(['Executive','Profissional']),
        host_primavera: yup.string().url(),
        username_primavera: yup.string(),
        password_primavera: yup.string(),
        instance_primavera: yup.string(),
        grant_type_primavera: yup.string(),
        company_primavera: yup.string(),
        conta_primavera: yup.string(),
        serie_primavera: yup.string(),
        tipo_documento_primavera: yup.string(),
        tipo_movimento_primavera: yup.string(),
        cambio_primavera: yup.number(),
      })

      logger("SERVIDOR:postClientes").debug(`Á validar os dados ${JSON.stringify(dados)}`)
      const validar = await schemaEndpoints.validate(dados)

      if(!validar.gpo_eventos && validar.para_servico == "REFERENCIAS"){
        validar.gpo_eventos = "PAID"
      }

      if(!validar.evento && validar.para_servico == "GPO"){
        validar.evento = "0"
      }

      const result = await models.postEndpoints(validar, req)    

      var wk = result.webhook 
      var lg = result.logs
      var nt = result.notification
        
      delete result.webhook
      delete result.logs
      delete result.notification
        
      res.status(result.statusCode).json(result)

      if(result.status == "sucesso"){

        if(dados?.para_servico == "GPO"){

          if(result?.endpoint){
            const queue = 'reference-entities';   
            const channel = await client.rabbitMQ.createChannel() 
            await channel.assertQueue(queue)
            const payload = JSON.stringify({
              kind: "webhook:created",
              body:{
                authorization: result?.endpoint.bearer_token,
                name: result?.endpoint.para_servico,
                verify_ssl: Boolean(result?.endpoint.verificar_ssl),
                hooks: [result?.endpoint.gpo_eventos],
                url: result?.endpoint.url,
                merchant_id: result?.endpoint.gpo_numero_comerciante
              }
            })
            channel.sendToQueue(queue, Buffer.from(payload));
            console.log("Cadastrar Webhook: Enviado para fila")
          }
        }
        
        sendRequestOnMicroservices({lg, nt, wk})
      }
      
  } catch (error) {
      console.error(error.message)
      logger("SERVIDOR:postClientes").error(`Erro ao cadastrar o cliente ${error.message}`)

      if(error?.path){
        const rs = response("erro", 412, error.message);
        res.status(rs.statusCode).json(rs)        
      }else{  
        const rs = response("erro", 400, `Algo aconteceu. Tente de novo, ${error.message}`);
        res.status(rs.statusCode).json(rs)
      }
  }
    
}

module.exports.patchEndpoints = async function(req, res, next) {
  try {

      logger("SERVIDOR:postClientes").info(`Iniciando cadastrado o cliente`)
      
      const dados =  req.body
      const {id_endpoint} =  req.params 

      const schemaEndpoints = yup.object().shape({
        url: yup.string().trim().url().required(),
        activo: yup.mixed().oneOf(['true', 'false']).default('true'), 
        evento: yup.number(),
        bearer_token: yup.string(),
        entidade_aceite: yup.string().min(5).required(),
        verificar_ssl: yup.mixed().oneOf(['true', 'false']).default('true'),
        tipo_endpoint: yup.mixed().oneOf(['NORMAL', 'PRIMAVERA','VENDUS']).required(),
        para_servico: yup.mixed().oneOf(['REFERENCIAS', 'GPO']).default('REFERENCIAS').required(),
        gpo_eventos: yup.string().oneOf(['PAID', 'PAID,REJECTD', 'PAID,REFUNDED', 'PAID,REJECTD,REFUNDED', 'REJECTD', 'REJECTD,REFUNDED', 'REFUNDED']).default('PAID'),
        campo_codigo_cliente_primavera: yup.mixed().oneOf(['opcional_1','opcional_2','opcional_3']).default('opcional_1'),
        tipo_resposta: yup.mixed().oneOf(['Completa','Resumida','Formatada']).required().default('Completa'),
        line_primavera: yup.mixed().oneOf(['Executive','Profissional']),
        host_primavera: yup.string().url(),
        username_primavera: yup.string(),
        password_primavera: yup.string(),
        instance_primavera: yup.string(),
        grant_type_primavera: yup.string(),
        company_primavera: yup.string(),
        conta_primavera: yup.string(),
        serie_primavera: yup.string(),
        tipo_documento_primavera: yup.string(),
        tipo_movimento_primavera: yup.string(),
        cambio_primavera: yup.number(),
      })

      logger("SERVIDOR:postClientes").debug(`Á validar os dados ${JSON.stringify(dados)}`)
      const validar = await schemaEndpoints.validate(dados)

      if(!validar.gpo_eventos && validar.para_servico == "REFERENCIAS"){
        validar.gpo_eventos = "PAID"
      } 

      if(!validar.evento && validar.para_servico == "GPO"){
        validar.evento = "0"
      }

      const result = await models.patchEndpoints(id_endpoint, validar, req)

      var wk = result.webhook
      var lg = result.logs
      var nt = result.notification
      
      delete result.webhook
      delete result.logs
      delete result.notification
      
      res.status(result.statusCode).json(result)
      
      if(result.status == "sucesso"){
        
        if(dados?.para_servico == "GPO"){

          if(result?.endpoint){
            const queue = 'reference-entities';   
            const channel = await client.rabbitMQ.createChannel() 
            await channel.assertQueue(queue)
            const payload = JSON.stringify({
              kind: "webhook:updated",
              body:{
                authorization: result?.endpoint.bearer_token,
                name: result?.endpoint.para_servico,
                verify_ssl: Boolean(result?.endpoint.verificar_ssl),
                hooks: [result?.endpoint.gpo_eventos],
                url: result?.endpoint.url,
                merchant_id: result?.endpoint.gpo_numero_comerciante
              }
            })  
            channel.sendToQueue(queue, Buffer.from(payload));
            console.log("Actualizar Webhook: Enviado para fila")
          }
        }

        sendRequestOnMicroservices({lg, nt, wk})
      }
    

  } catch (error) {
      console.error(error.message)
      logger("SERVIDOR:postClientes").error(`Erro ao cadastrar o cliente ${error.message}`)

      if(error?.path){
        const rs = response("erro", 412, error.message);
        res.status(rs.statusCode).json(rs)        
      }else{  
        const rs = response("erro", 400, `Algo aconteceu. Tente de novo, ${error.message}`);
        res.status(rs.statusCode).json(rs)
      }
  }
    
}

module.exports.patchEndpointsAlternarEstado = async function(req, res, next) {
  try {

      logger("SERVIDOR:postClientes").info(`Iniciando cadastrado o cliente`)
      
      const dados =  req.body
      const {id_endpoint} =  req.params 

      const schemaEndpoints = yup.object().shape({
        activo: yup.mixed().oneOf(['true', 'false']).required(),
      })

      logger("SERVIDOR:postClientes").debug(`Á validar os dados ${JSON.stringify(dados)}`)
      const validar = await schemaEndpoints.validate(dados)
      validar.activo = validar.activo == "true" ? "false" : "true"
      const result = await models.patchEndpoints(id_endpoint, validar, req)

      var wk = result.webhook
      var lg = result.logs
      var nt = result.notification
      
      delete result.webhook
      delete result.logs
      delete result.notification
      
      res.status(result.statusCode).json(result)
      
      if(result.status == "sucesso"){
        
        sendRequestOnMicroservices({lg, nt, wk})

        if(dados?.para_servico == "GPO"){

          if(result?.endpoint){
            const queue = 'reference-entities';   
            const channel = await client.rabbitMQ.createChannel() 
            await channel.assertQueue(queue)
            const payload = JSON.stringify({
              kind: "webhook:updated",
              body:{
                authorization: result?.endpoint.bearer_token,
                name: result?.endpoint.para_servico,
                verify_ssl: Boolean(result?.endpoint.verificar_ssl),
                hooks: [result?.endpoint.gpo_eventos],
                url: result?.endpoint.url,
                merchant_id: result?.endpoint.gpo_numero_comerciante
              }
            })  
            channel.sendToQueue(queue, Buffer.from(payload));
            console.log("Actualizar Webhook: Enviado para fila")
          }
        }

      }
    

  } catch (error) {
      console.error(error.message)
      logger("SERVIDOR:postClientes").error(`Erro ao cadastrar o cliente ${error.message}`)

      if(error?.path){
        const rs = response("erro", 412, error.message);
        res.status(rs.statusCode).json(rs)        
      }else{  
        const rs = response("erro", 400, `Algo aconteceu. Tente de novo, ${error.message}`);
        res.status(rs.statusCode).json(rs)
      }
  }
    
}

module.exports.deleteEndpoints = async function(req, res, next) {
  try {

      const {id_endpoint} =  req.params 
      const result = await models.deleteEndpoints(id_endpoint, req)

      var wk = result.webhook
      var lg = result.logs
      var nt = result.notification
      
      delete result.webhook
      delete result.logs
      delete result.notification
      
      res.status(result.statusCode).json(result)
        
      if(result.status == "sucesso"){
        
        sendRequestOnMicroservices({lg, nt, wk})
      }
      

  } catch (error) {
      console.error(error.message)
      logger("SERVIDOR:postClientes").error(`Erro ao cadastrar o cliente ${error.message}`)
        const rs = response("erro", 400, `Algo aconteceu. Tente de novo, ${error.message}`);
        res.status(rs.statusCode).json(rs)
  }
    
}