const { PrismaClient: MSGClient } = require("../../prisma/clients/msg"); const logger = require("./logger.services.js"); const msgPrisma = new MSGClient(); class SocketService { constructor(io) { this.io = io; this.setupSocketHandlers(); } setupSocketHandlers() { this.io.on('connection', (socket) => { logger.info(`New client connected: ${socket.id}`); socket.on('join_conversation', (data) => { this.handleJoinConversation(socket, data); }); socket.on('send_message', async (data) => { await this.handleSendMessage(socket, data); }); socket.on('typing_start', (data) => { this.handleTypingStart(socket, data); }); socket.on('typing_stop', (data) => { this.handleTypingStop(socket, data); }); socket.on('disconnect', () => { this.handleDisconnect(socket); }); }); } handleJoinConversation(socket, data) { const { conversationId, userId, userType } = data; socket.join(conversationId); socket.userId = userId; socket.userType = userType; logger.info(`${userType} ${userId} joined conversation ${conversationId}`); socket.to(conversationId).emit('user_joined', { userId, userType, message: `${userType} joined the conversation` }); } async handleSendMessage(socket, data) { try { const { conversationId, message, senderId, senderType, messageType = 'text' } = data; const savedMessage = await this.saveMessageToDatabase({ conversationId, message, senderId, senderType, messageType }); this.io.to(conversationId).emit('receive_message', savedMessage); logger.info(`Message sent in conversation ${conversationId} by ${senderType} ${senderId}`); } catch (error) { logger.error('Error sending message:', error); socket.emit('message_error', { error: 'Failed to send message', details: error.message }); } } handleTypingStart(socket, data) { const { conversationId, userId, userType } = data; socket.to(conversationId).emit('user_typing', { userId, userType }); } handleTypingStop(socket, data) { const { conversationId, userId, userType } = data; socket.to(conversationId).emit('user_stopped_typing', { userId, userType }); } handleDisconnect(socket) { logger.info(`Client disconnected: ${socket.id}`); if (socket.userId && socket.userType) { // You might want to emit to specific rooms the user was in // This would require tracking which rooms the user was in } } async saveMessageToDatabase(messageData) { try { const message = await msgPrisma.messages.create({ data: { conversationId: messageData.conversationId, content: messageData.message, messageType: messageData.messageType || 'text', senderId: messageData.senderId, senderType: messageData.senderType, senderName: messageData.senderName, status: 'sent', metadata: messageData.metadata || {} }, include: { conversation: true } }); await msgPrisma.conversations.update({ where: { id: messageData.conversationId }, data: { lastMessageAt: new Date() } }); return { id: message.id, conversationId: message.conversationId, message: message.content, senderId: message.senderId, senderType: message.senderType, senderName: message.senderName, messageType: message.messageType, timestamp: message.createdAt.toISOString(), status: message.status }; } catch (error) { logger.error('Error saving message to database:', error); throw error; } } sendMessageToConversation(conversationId, messageData) { this.io.to(conversationId).emit('receive_message', messageData); } sendNotificationToUser(userId, notificationData) { this.io.emit('notification', { userId, ...notificationData }); } } module.exports = SocketService;