const express = require('express'); const router = express.Router(); const path = require('path'); const fs = require('fs').promises; const { logger } = require('../../../config/logs'); const collaborationFilePath = path.join(__dirname, '../../../data', 'collaboration.json'); // Fonction utilitaire pour lire le fichier de collaboration async function readCollaborationFile() { try { const exists = await fs.access(collaborationFilePath) .then(() => true) .catch(() => false); if (!exists) { await fs.writeFile(collaborationFilePath, JSON.stringify({ activeFiles: {} })); return { activeFiles: {} }; } const data = await fs.readFile(collaborationFilePath, 'utf8'); return JSON.parse(data); } catch (error) { logger.error('Error reading collaboration file:', error); return { activeFiles: {} }; } } // Fonction utilitaire pour écrire dans le fichier de collaboration async function writeCollaborationFile(data) { try { await fs.writeFile(collaborationFilePath, JSON.stringify(data, null, 2)); return true; } catch (error) { logger.error('Error writing collaboration file:', error); return false; } } router.post('/toggle', async (req, res) => { try { const { itemName, itemType, enable } = req.body; // Lire ou créer le fichier de collaboration let collaborationData = await readCollaborationFile(); // S'assurer que la structure est correcte if (!collaborationData.activeFiles) { collaborationData.activeFiles = {}; } // Mettre à jour le statut de collaboration const itemId = `${itemType}-${itemName}`; if (enable) { collaborationData.activeFiles[itemId] = { name: itemName, type: itemType, isCollaborative: true, activeUsers: [], lastModified: new Date().toISOString() }; } else { delete collaborationData.activeFiles[itemId]; } // Sauvegarder les changements await writeCollaborationFile(collaborationData); // Notifier via WebSocket si disponible if (req.app.get('wsManager')) { req.app.get('wsManager').broadcast({ type: 'collaborationStatus', itemName, itemType, isCollaborative: enable, activeUsers: collaborationData.activeFiles[itemId]?.activeUsers || [] }); } res.json({ success: true, isCollaborative: enable, activeUsers: collaborationData.activeFiles[itemId]?.activeUsers || [] }); } catch (error) { logger.error('Error in collaboration toggle:', error); res.status(500).json({ success: false, error: 'Internal server error' }); } }); // Route pour obtenir le statut d'un fichier router.get('/file-status/:fileId', async (req, res) => { try { const { fileId } = req.params; const collaboration = await readCollaborationFile(); res.json({ fileId, isCollaborative: true, activeUsers: collaboration.activeFiles[fileId]?.activeUsers || [], lastModified: collaboration.activeFiles[fileId]?.lastModified || null }); } catch (error) { logger.error('Error getting file status:', error); res.status(500).json({ error: 'Internal server error' }); } }); router.get('/searchuser', async (req, res) => { try { const { username } = req.query; const userFilePath = path.join(__dirname, '../../../data', 'user.json'); const users = JSON.parse(await fs.readFile(userFilePath, 'utf8')); const user = users.find(u => u.name.toLowerCase() === username.toLowerCase()); if (user) { res.json({ found: true, user: { id: user.id, name: user.name, profilePicture: user.profilePicture } }); } else { res.json({ found: false }); } } catch (error) { logger.error('Error searching user:', error); res.status(500).json({ error: 'Internal server error' }); } }); // Route pour rejoindre un fichier router.post('/join', async (req, res) => { try { const { itemName, itemType, userId } = req.body; const collaboration = await readCollaborationFile(); const itemId = `${itemType}-${itemName}`; if (!collaboration.activeFiles[itemId]) { collaboration.activeFiles[itemId] = { name: itemName, type: itemType, isCollaborative: true, activeUsers: [], lastModified: new Date().toISOString() }; } // Ajouter l'utilisateur si pas déjà présent if (!collaboration.activeFiles[itemId].activeUsers.find(u => u.id === userId)) { // Récupérer les infos de l'utilisateur const userFilePath = path.join(__dirname, '../../../data', 'user.json'); const users = JSON.parse(await fs.readFile(userFilePath, 'utf8')); const user = users.find(u => u.id === userId); if (user) { collaboration.activeFiles[itemId].activeUsers.push({ id: user.id, name: user.name, profilePicture: user.profilePicture, lastActive: new Date().toISOString() }); await writeCollaborationFile(collaboration); // Notifier via WebSocket if (req.app.get('wsManager')) { req.app.get('wsManager').broadcast({ type: 'collaborationStatus', itemName, itemType, isCollaborative: true, activeUsers: collaboration.activeFiles[itemId].activeUsers }); } } } res.json({ success: true }); } catch (error) { logger.error('Error in join collaboration:', error); res.status(500).json({ error: 'Internal server error' }); } }); // Route pour ajouter un collaborateur router.post('/add', async (req, res) => { try { const { itemName, itemType, userId } = req.body; const collaboration = await readCollaborationFile(); const itemId = `${itemType}-${itemName}`; if (!collaboration.activeFiles[itemId]) { return res.status(404).json({ error: 'Item not found in collaboration' }); } // Vérifier si l'utilisateur n'est pas déjà dans la liste if (!collaboration.activeFiles[itemId].activeUsers.find(u => u.id === userId)) { // Récupérer les infos de l'utilisateur const userFilePath = path.join(__dirname, '../../../data', 'user.json'); const users = JSON.parse(await fs.readFile(userFilePath, 'utf8')); const user = users.find(u => u.id === userId); if (user) { collaboration.activeFiles[itemId].activeUsers.push({ id: user.id, name: user.name, profilePicture: user.profilePicture, lastActive: new Date().toISOString() }); await writeCollaborationFile(collaboration); // Notifier via WebSocket if (req.app.get('wsManager')) { req.app.get('wsManager').broadcast({ type: 'collaborationStatus', itemName, itemType, isCollaborative: true, activeUsers: collaboration.activeFiles[itemId].activeUsers }); } res.json({ success: true }); } else { res.status(404).json({ error: 'User not found' }); } } else { res.status(400).json({ error: 'User already in collaboration' }); } } catch (error) { logger.error('Error adding collaborator:', error); res.status(500).json({ error: 'Internal server error' }); } }); // Route pour retirer un collaborateur router.post('/remove', async (req, res) => { try { const { itemName, itemType, userId } = req.body; const collaboration = await readCollaborationFile(); const itemId = `${itemType}-${itemName}`; if (!collaboration.activeFiles[itemId]) { return res.status(404).json({ error: 'Item not found in collaboration' }); } // Retirer l'utilisateur de la liste collaboration.activeFiles[itemId].activeUsers = collaboration.activeFiles[itemId].activeUsers.filter(user => user.id !== userId); await writeCollaborationFile(collaboration); // Notifier via WebSocket if (req.app.get('wsManager')) { req.app.get('wsManager').broadcast({ type: 'collaborationStatus', itemName, itemType, isCollaborative: true, activeUsers: collaboration.activeFiles[itemId].activeUsers }); } res.json({ success: true }); } catch (error) { logger.error('Error removing collaborator:', error); res.status(500).json({ error: 'Internal server error' }); } }); // Route pour quitter un fichier router.post('/leave', async (req, res) => { try { const { fileId } = req.body; const userId = req.user.id; if (!fileId || !userId) { return res.status(400).json({ error: 'FileId and userId are required' }); } const collaboration = await readCollaborationFile(); if (collaboration.activeFiles[fileId]) { collaboration.activeFiles[fileId].activeUsers = collaboration.activeFiles[fileId].activeUsers.filter(user => user.id !== userId); if (collaboration.activeFiles[fileId].activeUsers.length === 0) { delete collaboration.activeFiles[fileId]; } await writeCollaborationFile(collaboration); if (req.app.get('wsManager')) { req.app.get('wsManager').broadcastFileStatus(fileId); } } res.json({ success: true }); } catch (error) { logger.error('Error leaving file:', error); res.status(500).json({ error: 'Internal server error' }); } }); router.get('/status', async (req, res) => { try { const collaboration = await readCollaborationFile(); res.json({ items: collaboration.activeFiles }); } catch (error) { logger.error('Error getting collaboration status:', error); res.status(500).json({ error: 'Internal server error' }); } }); // Route pour obtenir les détails d'un élément collaboratif router.get('/details/:type/:name', async (req, res) => { try { const { type, name } = req.params; const collaboration = await readCollaborationFile(); const itemId = `${type}-${name}`; res.json(collaboration.activeFiles[itemId] || { isCollaborative: false, activeUsers: [] }); } catch (error) { logger.error('Error getting collaboration details:', error); res.status(500).json({ error: 'Internal server error' }); } }); // Route pour obtenir les utilisateurs actifs d'un élément router.get('/users/:type/:name', async (req, res) => { try { const { type, name } = req.params; const collaboration = await readCollaborationFile(); const itemId = `${type}-${name}`; const activeUsers = collaboration.activeFiles[itemId]?.activeUsers || []; res.json({ users: activeUsers }); } catch (error) { logger.error('Error getting active users:', error); res.status(500).json({ error: 'Internal server error' }); } }); module.exports = router;