// socket.js - Quản lý Socket.IO instance và map userId → socketId

let io = null;

// Map userId (string) → Set of socketIds (một user có thể mở nhiều tab)
const userSocketMap = new Map();

function initSocket(httpServer) {
    const { Server } = require('socket.io');
    io = new Server(httpServer, {
        cors: {
            origin: process.env.URL_CLIENT,
            credentials: true,
        },
    });

    io.on('connection', (socket) => {
        console.log('[Socket] Client connected:', socket.id);

        // Client gửi userId sau khi kết nối
        socket.on('join', (userId) => {
            if (!userId) return;
            socket.userId = userId;

            if (!userSocketMap.has(userId)) {
                userSocketMap.set(userId, new Set());
            }
            userSocketMap.get(userId).add(socket.id);
            console.log(`[Socket] User ${userId} joined with socket ${socket.id}`);
        });

        socket.on('disconnect', () => {
            const { userId } = socket;
            if (userId && userSocketMap.has(userId)) {
                userSocketMap.get(userId).delete(socket.id);
                if (userSocketMap.get(userId).size === 0) {
                    userSocketMap.delete(userId);
                }
            }
            console.log('[Socket] Client disconnected:', socket.id);
        });
    });

    return io;
}

/**
 * Emit sự kiện tới một user cụ thể theo userId
 * @param {string} userId
 * @param {string} event
 * @param {any} data
 */
function emitToUser(userId, event, data) {
    if (!io) return;
    const socketIds = userSocketMap.get(String(userId));
    if (socketIds && socketIds.size > 0) {
        socketIds.forEach((socketId) => {
            io.to(socketId).emit(event, data);
        });
        console.log(`[Socket] Emitted "${event}" to user ${userId}`);
    }
}

function getIO() {
    return io;
}

module.exports = { initSocket, emitToUser, getIO };
