import { Server } from "socket.io";
import Message from "../models/message.js";
import mongoose from "mongoose";
import ChatRoom from "../models/chat-room.js";

let io;
const activeUsers = new Map(); // Track active connections
const initSocket = (server) => {
  io = new Server(server, {
    cors: {
      origin: "*",
      methods: ["GET", "POST", "PUT", "DELETE"],
      allowedHeaders: ["Content-Type", "Authorization"],
    },
    transports: ["websocket", "polling"],
  });

  io.on("connection", (socket) => {
    console.log("A user connected:", socket.id);

    socket.on("register user", (userId) => {
      activeUsers.set(userId, socket.id);
      console.log(`User ${userId} registered with socket ${socket.id}`);
      console.log("Active users:", Array.from(activeUsers.entries()));
    });

    socket.on("join room", async ({ senderId, receiverId, senderRole }) => {
      const ids = [senderId.toString(), receiverId.toString()].sort();
      let finalRoomId = `${ids[0]}_${ids[1]}`;
      const existingRoom = await ChatRoom.findOne({ roomId: finalRoomId });
      let newRoom;
      console.log("Received senderRole:", senderRole);
      if (!existingRoom) {
        if (senderRole === "patient") {
          newRoom = new ChatRoom({
            roomId: finalRoomId,
            senderId: new mongoose.Types.ObjectId(senderId),
            receiverId: new mongoose.Types.ObjectId(receiverId),
          });
        } else if (senderRole === "doctor") {
          newRoom = new ChatRoom({
            roomId: finalRoomId,
            senderId: new mongoose.Types.ObjectId(receiverId), // 👈 watch spelling here — "receiverId" not "recieverId"
            receiverId: new mongoose.Types.ObjectId(senderId),
          });
        }

        if (newRoom) {
          await newRoom.save();
          console.log(`New room has been created: ${finalRoomId}`);
        } else {
          console.log("Failed to create room — unknown sender role.");
        }
      } else {
        console.log(`Room already exists: ${finalRoomId}`);
      }

      socket.join(finalRoomId);
      console.log(`Socket ${socket.id} joined room: ${finalRoomId}`);

      socket.emit("room joined", { roomId: finalRoomId, success: true });
    });

    socket.on("get previous messages", async ({ roomId }) => {
      try {
        const messages = await Message.find({ roomId })
          .sort({ createdAt: "asc" })
          .limit(50);

        // Transform messages to match your client's expected format
        const formattedMessages = messages.map((msg) => ({
          message: msg.message,
          senderId: msg.senderId.toString(), // Ensure senderId is a string
          timestamp: msg.createdAt,
        }));

        socket.emit("previous messages", formattedMessages);
      } catch (error) {
        console.error("Error fetching previous messages:", error);
        socket.emit("previous messages", []);
      }
    });

    socket.on("new message", async (data) => {
      const { roomId, message, senderId, receiverId } = data;
      console.log(`New message from room ${roomId}`, data);

      try {
        const newMessage = new Message({
          roomId,
          senderId,
          receiverId,
          message,
        });

        await newMessage.save();

        // Important fix: Use the actual senderId from the message
        // Not the room's senderId
        io.to(roomId).emit("receive message", {
          message: newMessage.message,
          senderId: newMessage.senderId.toString(), // Use the actual message sender ID
          receiverId: newMessage.receiverId.toString(),
          timestamp: newMessage.createdAt,
        });

        console.log("Message saved and broadcast:", {
          message: newMessage.message,
          senderId: newMessage.senderId.toString(),
          timestamp: newMessage.createdAt,
        });
      } catch (error) {
        console.log("Error saving message:", error);
      }
    });

    socket.on("disconnect", () => {
      console.log("A user disconnected:", socket.id);

      for (const [userId, socketId] of activeUsers.entries()) {
        if (socketId === socket.id) {
          activeUsers.delete(userId);
          console.log(`User ${userId} has been removed from active users`);
        }
      }
    });

    // Handle room leaving
    socket.on("leave room", ({ roomId }) => {
      socket.leave(roomId);
      console.log(`Socket ${socket.id} left room: ${roomId}`);
    });
  });
};

export default initSocket;

// import { Server } from "socket.io";
// import Message from "../models/message.js";
// import mongoose from "mongoose";
// import ChatRoom from "../models/chat-room.js";
//
// let io;
// const activeUsers = new Map(); // Track active connections
// const initSocket = (server) => {
//   io = new Server(server, {
//     cors: {
//       // origin: ["http://10.0.2.2:5000/api", "http://localhost:5000/api"],
//       origin: "*",
//       methods: ["GET", "POST", "PUT", "DELETE"],
//       allowedHeaders: ["Content-Type", "Authorization"],
//     },
//     transports: ["websocket", "polling"],
//   });
//
//   io.on("connection", (socket) => {
//     console.log("A user connected:", socket.id);
//
//     socket.on("register user", (userId) => {
//       activeUsers.set(userId, socket.id);
//       console.log(`User ${userId} registered with socket ${socket.id}`);
//       console.log("Active users:", Array.from(activeUsers.entries()));
//     });
//
//     socket.on("join room", async ({ senderId, receiverId }) => {
//       // socket.on("join room", async ({ senderId, receiverId}) => {
//       const ids = [senderId.toString(), receiverId.toString()].sort();
//       let finalRoomId = `${ids[0]}_${ids[1]}`;
//       const existingRoom = await ChatRoom.findOne({ roomId: finalRoomId });
//       if (!existingRoom) {
//         const newRoom = new ChatRoom({
//           roomId: finalRoomId,
//           senderId: new mongoose.Types.ObjectId(senderId),
//           receiverId: new mongoose.Types.ObjectId(receiverId),
//         });
//         await newRoom.save();
//         console.log("New room has been created: ${roomId}");
//       } else {
//         console.log("Room already exists: ${roomId}");
//       }
//       socket.join(finalRoomId);
//       console.log(`Socket ${socket.id} joined room: ${finalRoomId}`);
//
//       socket.emit("room joined", { roomId: finalRoomId, success: true });
//     });
//     socket.on("get previous messages", async ({ roomId }) => {
//       try {
//         const messages = await Message.find({ roomId })
//           .sort({ createdAt: "asc" })
//           .limit(50);
//
//         // Transform messages to match your client's expected format
//         const formattedMessages = messages.map((msg) => ({
//           message: msg.message,
//           senderId: msg.senderId,
//           // receiverId: msg.receiverId,
//           timestamp: msg.createdAt,
//           // Add any other fields you need
//         }));
//
//         socket.emit("previous messages", formattedMessages);
//       } catch (error) {
//         console.error("Error fetching previous messages:", error);
//         socket.emit("previous messages", []);
//       }
//     });
//     socket.on("new message", async (data) => {
//       // const { message, senderId, receiverId, mediaUrl } = data;
//       const { roomId, message, senderId, receiverId } = data;
//       // const { roomId, message } = data;
//       console.log(`New message from  room ${roomId}`);
//
//       try {
//         const newMessage = new Message({
//           roomId,
//           senderId,
//           receiverId,
//           message,
//           // mediaUrl
//         });
//
//         await newMessage.save();
//
//         const room = await ChatRoom.findOne({ roomId });
//         if (!room) {
//           console.error("Room not found!");
//         }
//
//         console.log("Emitting to room:", roomId);
//         console.log("Socket rooms:", io.sockets.adapter.rooms);
//
//         io.to(roomId).emit("receive message", {
//           // _id: newMessage._id,
//           message: newMessage.message,
//           senderId: room.senderId,
//           // receiverId: room.receiverId,
//           timestamp: newMessage.createdAt,
//           // mediaUrl: newMessage.mediaUrl,
//         });
//         console.log("Message saved:", newMessage);
//       } catch (error) {
//         console.log("Error saving message:", error);
//       }
//     });
//
//     // socket.on("typing", ({ senderId, receiverId }) => {
//     //   const ids = [senderId.toString(), receiverId.toString()].sort();
//     //   const roomId = `${ids[0]}_${ids[1]}`;
//     //   socket.broadcast.to(roomId).emit("typing", senderId);
//     // });
//
//     socket.on("disconnect", () => {
//       console.log("A user disconnected:", socket.id);
//
//       for (const [userId, socketId] of activeUsers.entries()) {
//         if (socketId === socket.id) {
//           activeUsers.delete(userId);
//           console.log(`User ${userId} has been removed from active users`);
//         }
//       }
//     });
//
//     // Handle room leaving
//     socket.on("leave room", ({ roomId }) => {
//       socket.leave(roomId);
//       console.log(`Socket ${socket.id} left room: ${roomId}`);
//     });
//   });
// };
//
// export default initSocket;
