const express = require("express");
//const twilio = require("./Twilio");
const bodyParser = require("body-parser");
const logger = require("morgan");
const axios = require("axios");

const cors = require("cors");
const http = require("http");
const socketIo = require("socket.io");
//const jwt = require("./utils/Jwt");
//const { getAccessTokenForVoice } = require("./Twilio");
//const { Twilio } = require("twilio");
//const { verify } = require("crypto");
const app = express();
const server = http.createServer(app);
const io = socketIo(server, {
   cors: {
      origin: "*", // Permitir todas las orígenes
      methods: ["GET", "POST"],
      allowedHeaders: ["my-custom-header"],
      credentials: true,
   },
   path: "/socket-chat-v1/socket.io", // Ruta personalizada
});

/* io.use((socket, next) => {
  console.log('Socket middleware');
  if (socket.handshake.query && socket.handshake.query.token) {
    const { token } = socket.handshake.query;
    try {
      const result = jwt.verifyToken(token);
      if (result.username) return next();
    } catch (error) {
      console.log(error);
    }
  }
}); */

//----------------------------SE PUEDE HACE ASI USANDO of--------------------------------------------

//o de esta forma que es como trabajaremos
io.on("connection", (socket) => {
   console.log("Socket connected", socket.id);
   
   socket.on("join-chat-room", (db) => {
      if (db) {
         const room = `chat_room_${db}`;
         socket.join(room);
         console.log(`Socket ${socket.id} joined room: ${room}`);
      }
   })
   
   //socket.emit("twilio-token", { token: getAccessTokenForVoice("cesar") });
   socket.on("disconnect", () => {
      console.log("Socket disconnected", socket.id);
   });

   socket.on("chat-social", (data) => {
      console.log("mensaje de chat social", data);
      
      const { db } = data;

      // VALIDACIÓN BÁSICA
      if (!db) {
        console.log("Falta db, no se emite a room");
        return;
      }

      /* io.emit(`chat-social/${data.id}`, {
         tipo_producto: data.tipo_producto,
         mensaje: data.mensaje,
      }); */

      //io.emit(`chat-social-empleados/${data.db}/${data.staff_id}`, data);
      
      const room = `chat_room_${db}`;

      io.to(room).emit(
         `chat-social-empleados/${data.db}/${data.staff_id}/${data.config_whatsapp_other_id}`,
         data,
      );

      //parte del administrador
      io.to(room).emit(`chat-social`, data);

      io.to(room).emit(`chat-social/${data.db}`, data);
   });

   //para empleados
   socket.on("add-contactos-empleados", (data) => {
      //io.emit(`add-contactos-empleados/${data.db}/${data.staff_id}`, data);
      
     const { db } = data;

      // VALIDACIÓN BÁSICA
      if (!db) {
        console.log("Falta db, no se emite a room");
        return;
      }
 
      const room = `chat_room_${db}`;
      
      io.to(room).emit(`add-contactos-empleados/${data.db}`, data);
   });

   socket.on("chat-social-otros-mensajes", (data) => {
       
      const { db } = data;

      // VALIDACIÓN BÁSICA
      if (!db) {
        console.log("Falta db, no se emite a room");
        return;
      }
 
      const room = `chat_room_${db}`;
       
      io.to(room).emit(`chat-social-otros-mensajes/${data.db}`, data);
   });
   
   //usamos para ver si los staff estan en linea o no
   socket.on("estado-online-staff", (data) => {
       
      const { db } = data;

      // VALIDACIÓN BÁSICA
      if (!db) {
        console.log("Falta db, no se emite a room");
        return;
      }
 
      const room = `chat_room_${db}`;
      
      io.to(room).emit(`estado-online-staff/${data.db}`, data);
      
      //io.emit(`estado-online-staff/${data.db}`, data);
   });

   //para Admin
   socket.on("change-customer-admin", (data) => {
       
      const { db } = data;

      // VALIDACIÓN BÁSICA
      if (!db) {
        console.log("Falta db, no se emite a room");
        return;
      }
 
      const room = `chat_room_${db}`; 
       
      io.to(room).emit(`change-customer-admin/${data.db}`, data);
   });

    //usamos para ver si los staff estan en linea o no
   socket.on("procesos-partners", (data) => {
      io.emit(`procesos-partners/${data.UUID_ENC}`, data);
   });
   
   //lo usaremos en invoices
   socket.on("invoices-status", (data) => {
      console.log("mensaje de chat social", data);
      
      const { db } = data;

      // VALIDACIÓN BÁSICA
      if (!db) {
        console.log("Falta db, no se emite a room");
        return;
      }
 
      const room = `chat_room_${db}`; 
      
       //parte del administrador
      io.to(room).emit(`invoices-status`, data);
   
      io.to(room).emit(
         `invoices-status/${data.db}/${data.id_invoices}`,
         data,
      );
 
   });
   
   //lo usaremos para notificar tickets
   socket.on("new-ticket-notification", (data) => {
      console.log("new-ticket-notification", data);
      
      const { db } = data;

      // VALIDACIÓN BÁSICA
      if (!db) {
        console.log("Falta db, no se emite a room");
        return;
      }
 
      const room = `chat_room_${db}`; 
      
       //parte del administrador
      io.to(room).emit(`new-ticket-notification`, data);
   
      io.to(room).emit(
         `new-ticket-notification/${data.db}`,
         data,
      );
 
   });
    

   socket.on("position", (data) => {
      console.log("CLIENTE EMITIO: ", data);
      io.emit(`position/${data.id_order}`, {
         id_order: data.id_order,
         lat: data.lat,
         lng: data.lng,
         estadoId: data.estadoId,
      });

      io.emit(`position`, data);
   });

   socket.on("chat-sistema", (data) => {
      //console.log("mensaje de chat social", data);
      
      const { db } = data;

      // VALIDACIÓN BÁSICA
      if (!db) {
        console.log("Falta db, no se emite a room");
        return;
      }
 
      const room = `chat_room_${db}`; 

      io.to(room).emit(`chat-sistema-usuarios/${data.db}/${data.user_id}`, data);
   });

   socket.on("chat-sistema-marcar-chat-leidos", (data) => {
      //console.log("mensaje de chat social", data);
      
      const { db } = data;

      // VALIDACIÓN BÁSICA
      if (!db) {
        console.log("Falta db, no se emite a room");
        return;
      }
 
      const room = `chat_room_${db}`;

      io.to(room).emit(
         `chat-sistema-oir-chat-leidos-usuarios/${data.db}/${data.user_id}`,
         data,
      );
   });
});


app.use(logger("dev"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cors());

const PORT = 10001;

app.get("/socket-chat-v1/", (req, res) => {
   res.send(
      "Bienvenidos al Socket, si lees este mensaje quiero decirte que el socket funciona. Quieres probar otra ruta te recomiento: /test",
   );
});

app.get("/socket-chat-v1/test", (req, res) => {
   /* io.emit("chat-social", {
      tipo_producto: "producto2",
      mensaje: "Desde test",
      id: 1,
   });

   io.emit("position", {
      id_order: "10000",
      lat: 112,
      lng: 223,
      estadoId: 1,
   }); */
   res.send("Hola soy la ruta test");
});

app.post("/socket-chat/mensajes", async (req, res) => {
   //const { to, code, username } = req.body;

   // io.emit("chat-social", req.body);

   try {
      // Obtener los valores de los parámetros de consulta 'db' y 'url'
      const db = req.query.db;
      const apiUrl =
         "https://xhde365.com/" + req.query.url + "/?ng=webhooks_sms";

      // Obtener el cuerpo de la solicitud
      let data = req.body;

      // Agregar los parámetros 'db' y 'url' al cuerpo de la solicitud
      data.db = db;
      data.apiUrl = apiUrl;

      // Emitir el evento del socket con el cuerpo modificado
      //io.emit("chat-social", data);

      // Configurar la petición axios
      await axios.post(apiUrl, data, {
         headers: {
            "Content-Type": "application/json",
         },
      });

      // Manejar la respuesta de la API
      return res.json({
         message: "Datos enviados con éxito",
      });
   } catch (error) {
      console.error("Error al consumir la API:", error);
      return res.status(500).json({
         message: "Error al consumir la API",
         error: error.message,
      });
   }

   return res.send("data enviada");
});

app.post("/socket-chat/mensajes/status", async (req, res) => {
   //const { to, code, username } = req.body;

   // io.emit("chat-social", req.body);

   try {
      // Obtener los valores de los parámetros de consulta 'db' y 'url'
      const db = req.query.db;
      const apiUrl =
         "https://xhde365.com/" +
         req.query.url +
         "/?ng=webhooks_sms_status_callback";

      // Obtener el cuerpo de la solicitud
      let data = req.body;

      // Agregar los parámetros 'db' y 'url' al cuerpo de la solicitud
      data.db = db;
      data.apiUrl = apiUrl;

      // Emitir el evento del socket con el cuerpo modificado
      //io.emit("chat-social", data);

      // Configurar la petición axios
      await axios.post(apiUrl, data, {
         headers: {
            "Content-Type": "application/json",
         },
      });

      // Manejar la respuesta de la API
      return res.json({
         message: "Datos enviados con éxito",
      });
   } catch (error) {
      console.error("Error al consumir la API:", error);
      return res.status(500).json({
         message: "Error al consumir la API",
         error: error.message,
      });
   }

   return res.send("data enviada");
});

app.post("/socket-chat-v1/mensajes_v1", async (req, res) => {
   //const { to, code, username } = req.body;

   // io.emit("chat-social", req.body);

   try {
      // Obtener los valores de los parámetros de consulta 'db' y 'url'
      const db = req.query.db;
      const apiUrl = "https://" + req.query.url + "/?ng=webhooks_sms";

      // Obtener el cuerpo de la solicitud
      let data = req.body;

      // Agregar los parámetros 'db' y 'url' al cuerpo de la solicitud
      data.db = db;
      data.apiUrl = apiUrl;

      // Emitir el evento del socket con el cuerpo modificado
      //io.emit("chat-social", data);

      // Configurar la petición axios
      await axios.post(apiUrl, data, {
         headers: {
            "Content-Type": "application/json",
         },
      });

      // Manejar la respuesta de la API
      return res.json({
         message: "Datos enviados con éxito",
      });
   } catch (error) {
      console.error("Error al consumir la API:", error);
      return res.status(500).json({
         message: "Error al consumir la API",
         error: error.message,
      });
   }

   return res.send("data enviada");
});

app.post("/socket-chat-v1/mensajes_v1/status_v1", async (req, res) => {
   //const { to, code, username } = req.body;

   // io.emit("chat-social", req.body);

   try {
      // Obtener los valores de los parámetros de consulta 'db' y 'url'
      const db = req.query.db;
      //const apiUrl =
      //   "https://xhde365.com/" +
      //   req.query.url +
      //   "/?ng=webhooks_sms_status_callback";
        //itgrahnpro.xhde365.com
      const apiUrl =
         "https://" + req.query.url + "/?ng=webhooks_sms_status_callback";

      // Obtener el cuerpo de la solicitud
      let data = req.body;

      // Agregar los parámetros 'db' y 'url' al cuerpo de la solicitud
      data.db = db;
      data.apiUrl = apiUrl;

      // Emitir el evento del socket con el cuerpo modificado
      //io.emit("chat-social", data);

      // Configurar la petición axios
      await axios.post(apiUrl, data, {
         headers: {
            "Content-Type": "application/json",
         },
      });

      // Manejar la respuesta de la API
      return res.json({
         message: "Datos enviados con éxito",
      });
   } catch (error) {
      console.error("Error al consumir la API:", error);
      return res.status(500).json({
         message: "Error al consumir la API",
         error: error.message,
      });
   }

   return res.send("data enviada");
});

/* app.post("/verify", async (req, res) => {
   //const { to, code, username } = req.body;

   console.log("Verifing code ", req.body);

   return res.send({ verify: "api verificado" });
});
 */

server.listen(PORT, () => {
   console.log(`Listening on PORT: ${PORT}`);
});
