const WebSocket = require('ws');

const wss = new WebSocket.Server({ port: 45678 });

const rooms = new Map();

console.log('Imators Meeting Server started on port 45678');

wss.on('connection', (ws) => {
    console.log('New client connected');
    
    let currentRoom = null;
    let currentUserId = null;

    ws.on('message', (data) => {
        try {
            const message = JSON.parse(data);
            
            switch (message.type) {
                case 'join':
                    handleJoin(ws, message);
                    break;
                case 'leave':
                    handleLeave(ws, message);
                    break;
                case 'offer':
                case 'answer':
                case 'ice-candidate':
                    handleSignaling(ws, message);
                    break;
                case 'chat':
                    handleChat(ws, message);
                    break;
                case 'video-toggle':
                    handleVideoToggle(ws, message);
                    break;
                case 'meeting-ended':
                    handleMeetingEnded(ws, message);
                    break;
            }
        } catch (error) {
            console.error('Error parsing message:', error);
        }
    });

    ws.on('close', () => {
        console.log('Client disconnected');
        if (currentRoom && currentUserId) {
            handleLeave(ws, { userId: currentUserId });
        }
    });

    function handleJoin(ws, message) {
        const { meetingId, userId, userName, userProfilePic } = message;
        
        currentRoom = meetingId;
        currentUserId = userId;
        
        if (!rooms.has(meetingId)) {
            rooms.set(meetingId, new Map());
        }
        
        const room = rooms.get(meetingId);
        room.set(userId, { ws, userName, userProfilePic });
        
        console.log(`User ${userName} joined room ${meetingId}`);
        
        room.forEach((client, clientId) => {
            if (clientId !== userId && client.ws.readyState === WebSocket.OPEN) {
                client.ws.send(JSON.stringify({
                    type: 'user-joined',
                    userId: userId,
                    userName: userName,
                    userProfilePic: userProfilePic
                }));
            }
        });
    }

    function handleLeave(ws, message) {
        if (!currentRoom || !currentUserId) return;
        
        const room = rooms.get(currentRoom);
        if (!room) return;
        
        const user = room.get(currentUserId);
        const userName = user ? user.userName : 'Unknown';
        
        room.delete(currentUserId);
        
        console.log(`User ${userName} left room ${currentRoom}`);
        
        room.forEach((client) => {
            if (client.ws.readyState === WebSocket.OPEN) {
                client.ws.send(JSON.stringify({
                    type: 'user-left',
                    userId: currentUserId,
                    userName: userName
                }));
            }
        });
        
        if (room.size === 0) {
            rooms.delete(currentRoom);
        }
    }

    function handleSignaling(ws, message) {
        if (!currentRoom) return;
        
        const room = rooms.get(currentRoom);
        if (!room) return;
        
        const targetClient = room.get(message.targetId);
        if (targetClient && targetClient.ws.readyState === WebSocket.OPEN) {
            const user = room.get(currentUserId);
            targetClient.ws.send(JSON.stringify({
                ...message,
                fromId: currentUserId,
                userName: user?.userName,
                userProfilePic: user?.userProfilePic
            }));
        }
    }

    function handleChat(ws, message) {
        if (!currentRoom) return;
        
        const room = rooms.get(currentRoom);
        if (!room) return;
        
        room.forEach((client) => {
            if (client.ws.readyState === WebSocket.OPEN) {
                client.ws.send(JSON.stringify({
                    type: 'chat',
                    message: message.message,
                    userName: message.userName,
                    timestamp: message.timestamp
                }));
            }
        });
    }

    function handleVideoToggle(ws, message) {
        if (!currentRoom) return;
        
        const room = rooms.get(currentRoom);
        if (!room) return;
        
        room.forEach((client, clientId) => {
            if (clientId !== currentUserId && client.ws.readyState === WebSocket.OPEN) {
                client.ws.send(JSON.stringify({
                    type: 'video-toggle',
                    userId: message.userId,
                    videoEnabled: message.videoEnabled
                }));
            }
        });
    }

    function handleMeetingEnded(ws, message) {
        if (!currentRoom) return;
        
        const room = rooms.get(currentRoom);
        if (!room) return;
        
        room.forEach((client) => {
            if (client.ws.readyState === WebSocket.OPEN) {
                client.ws.send(JSON.stringify({
                    type: 'meeting-ended'
                }));
                client.ws.close();
            }
        });
        
        rooms.delete(currentRoom);
    }
});