import websocket from '@fastify/websocket';
import fs from 'fs';
import path from 'path';
import { authenticateWs } from './ws-auth.js';
import { WsRooms } from './ws-rooms.js';
export async function registerWebSocket(app, jwtSecret, squadsDir = '') {
    const rooms = new WsRooms();
    let chatHandler = null;
    await app.register(websocket);
    app.get('/ws', { websocket: true }, (socket, request) => {
        const user = authenticateWs(request.url, request.headers.cookie, jwtSecret);
        if (!user) {
            socket.close(4001, 'Authentication required');
            return;
        }
        // Attach user info to socket for reference
        socket.user = user;
        socket.on('message', (raw) => {
            try {
                const msg = JSON.parse(raw.toString());
                handleMessage(socket, user, msg, rooms, chatHandler, squadsDir);
            }
            catch (err) {
                console.error('[ws] Error handling message:', err);
                // Try to send error back to client for chat messages
                try {
                    const msg = JSON.parse(raw.toString());
                    if (msg.type === 'chat:send' && msg.squadName) {
                        const errorPayload = {
                            type: 'chat:error',
                            squadName: msg.squadName,
                            error: err instanceof Error ? err.message : 'Internal server error',
                        };
                        socket.send(JSON.stringify(errorPayload));
                    }
                }
                catch { /* ignore */ }
            }
        });
        socket.on('close', () => {
            rooms.removeClient(socket);
        });
    });
    const broadcastToSquad = (squadName, data) => {
        rooms.broadcast(`squad:${squadName}`, JSON.stringify(data));
    };
    const broadcastToAll = (data) => {
        rooms.broadcastAll(JSON.stringify(data));
    };
    const setChatHandler = (handler) => {
        chatHandler = handler;
    };
    const getChatHandler = () => chatHandler;
    return { rooms, broadcastToSquad, broadcastToAll, setChatHandler, getChatHandler };
}
function handleMessage(ws, user, msg, rooms, chatHandler, squadsDir = '') {
    switch (msg.type) {
        case 'squad:subscribe':
            if (typeof msg.squadName === 'string') {
                rooms.subscribe(ws, `squad:${msg.squadName}`);
            }
            break;
        case 'squad:unsubscribe':
            if (typeof msg.squadName === 'string') {
                rooms.unsubscribe(ws, `squad:${msg.squadName}`);
            }
            break;
        case 'chat:send':
            if (typeof msg.squadName === 'string' && typeof msg.message === 'string' && chatHandler) {
                if (user.role === 'viewer') {
                    ws.send(JSON.stringify({
                        type: 'chat:error',
                        squadName: msg.squadName,
                        error: 'Insufficient permissions',
                    }));
                    return;
                }
                const files = Array.isArray(msg.files) ? msg.files : undefined;
                chatHandler.handleChatSend(msg.squadName, msg.message, files);
            }
            break;
        case 'chat:new_conversation':
            if (typeof msg.squadName === 'string' && chatHandler) {
                if (user.role === 'viewer') {
                    ws.send(JSON.stringify({
                        type: 'chat:error',
                        squadName: msg.squadName,
                        error: 'Insufficient permissions',
                    }));
                    return;
                }
                chatHandler.handleNewConversation(msg.squadName);
            }
            break;
        case 'squad:checkpoint_response':
            if (typeof msg.squadName === 'string' && typeof msg.answer === 'string') {
                if (user.role === 'viewer') {
                    ws.send(JSON.stringify({
                        type: 'squad:error',
                        squadName: msg.squadName,
                        error: 'Insufficient permissions',
                    }));
                    return;
                }
                try {
                    const squadDir = path.join(squadsDir, msg.squadName);
                    const filePath = path.join(squadDir, 'checkpoint-response.json');
                    fs.writeFileSync(filePath, JSON.stringify({
                        answer: msg.answer,
                        timestamp: new Date().toISOString(),
                    }));
                }
                catch {
                    // Silently handle missing squad directories
                }
            }
            break;
        default:
            break;
    }
}
//# sourceMappingURL=ws-handler.js.map