const express = require('express'); const { authenticateToken } = require('../middleware/auth'); const db = require('../database'); const router = express.Router(); // Get all sessions router.get('/', (req, res) => { try { const sessions = db.prepare(` SELECT s.*, COUNT(sg.id) as games_played FROM sessions s LEFT JOIN session_games sg ON s.id = sg.session_id GROUP BY s.id ORDER BY s.created_at DESC `).all(); res.json(sessions); } catch (error) { res.status(500).json({ error: error.message }); } }); // Get active session router.get('/active', (req, res) => { try { const session = db.prepare(` SELECT s.*, COUNT(sg.id) as games_played FROM sessions s LEFT JOIN session_games sg ON s.id = sg.session_id WHERE s.is_active = 1 GROUP BY s.id LIMIT 1 `).get(); if (!session) { return res.status(404).json({ error: 'No active session found' }); } res.json(session); } catch (error) { res.status(500).json({ error: error.message }); } }); // Get single session by ID router.get('/:id', (req, res) => { try { const session = db.prepare(` SELECT s.*, COUNT(sg.id) as games_played FROM sessions s LEFT JOIN session_games sg ON s.id = sg.session_id WHERE s.id = ? GROUP BY s.id `).get(req.params.id); if (!session) { return res.status(404).json({ error: 'Session not found' }); } res.json(session); } catch (error) { res.status(500).json({ error: error.message }); } }); // Create new session (admin only) router.post('/', authenticateToken, (req, res) => { try { const { notes } = req.body; // Check if there's already an active session const activeSession = db.prepare('SELECT id FROM sessions WHERE is_active = 1').get(); if (activeSession) { return res.status(400).json({ error: 'An active session already exists. Please close it before creating a new one.', activeSessionId: activeSession.id }); } const stmt = db.prepare(` INSERT INTO sessions (notes, is_active) VALUES (?, 1) `); const result = stmt.run(notes || null); const newSession = db.prepare('SELECT * FROM sessions WHERE id = ?').get(result.lastInsertRowid); res.status(201).json(newSession); } catch (error) { res.status(500).json({ error: error.message }); } }); // Close/finalize session (admin only) router.post('/:id/close', authenticateToken, (req, res) => { try { const { notes } = req.body; const session = db.prepare('SELECT * FROM sessions WHERE id = ?').get(req.params.id); if (!session) { return res.status(404).json({ error: 'Session not found' }); } if (session.is_active === 0) { return res.status(400).json({ error: 'Session is already closed' }); } const stmt = db.prepare(` UPDATE sessions SET is_active = 0, closed_at = CURRENT_TIMESTAMP, notes = COALESCE(?, notes) WHERE id = ? `); stmt.run(notes || null, req.params.id); const closedSession = db.prepare('SELECT * FROM sessions WHERE id = ?').get(req.params.id); res.json(closedSession); } catch (error) { res.status(500).json({ error: error.message }); } }); // Get games played in a session router.get('/:id/games', (req, res) => { try { const games = db.prepare(` SELECT sg.*, g.pack_name, g.title, g.game_type, g.min_players, g.max_players, g.popularity_score FROM session_games sg JOIN games g ON sg.game_id = g.id WHERE sg.session_id = ? ORDER BY sg.played_at ASC `).all(req.params.id); res.json(games); } catch (error) { res.status(500).json({ error: error.message }); } }); // Add game to session (admin only) router.post('/:id/games', authenticateToken, (req, res) => { try { const { game_id, manually_added } = req.body; if (!game_id) { return res.status(400).json({ error: 'game_id is required' }); } // Verify session exists and is active const session = db.prepare('SELECT * FROM sessions WHERE id = ?').get(req.params.id); if (!session) { return res.status(404).json({ error: 'Session not found' }); } if (session.is_active === 0) { return res.status(400).json({ error: 'Cannot add games to a closed session' }); } // Verify game exists const game = db.prepare('SELECT * FROM games WHERE id = ?').get(game_id); if (!game) { return res.status(404).json({ error: 'Game not found' }); } // Add game to session const stmt = db.prepare(` INSERT INTO session_games (session_id, game_id, manually_added) VALUES (?, ?, ?) `); const result = stmt.run(req.params.id, game_id, manually_added ? 1 : 0); // Increment play count for the game db.prepare('UPDATE games SET play_count = play_count + 1 WHERE id = ?').run(game_id); const sessionGame = db.prepare(` SELECT sg.*, g.pack_name, g.title, g.game_type FROM session_games sg JOIN games g ON sg.game_id = g.id WHERE sg.id = ? `).get(result.lastInsertRowid); res.status(201).json(sessionGame); } catch (error) { res.status(500).json({ error: error.message }); } }); // Import chat log and process popularity (admin only) router.post('/:id/chat-import', authenticateToken, (req, res) => { try { const { chatData } = req.body; if (!chatData || !Array.isArray(chatData)) { return res.status(400).json({ error: 'chatData must be an array' }); } const session = db.prepare('SELECT * FROM sessions WHERE id = ?').get(req.params.id); if (!session) { return res.status(404).json({ error: 'Session not found' }); } // Get all games played in this session with timestamps const sessionGames = db.prepare(` SELECT sg.game_id, sg.played_at, g.title FROM session_games sg JOIN games g ON sg.game_id = g.id WHERE sg.session_id = ? ORDER BY sg.played_at ASC `).all(req.params.id); if (sessionGames.length === 0) { return res.status(400).json({ error: 'No games played in this session to match votes against' }); } let votesProcessed = 0; const votesByGame = {}; const insertChatLog = db.prepare(` INSERT INTO chat_logs (session_id, chatter_name, message, timestamp, parsed_vote) VALUES (?, ?, ?, ?, ?) `); const updatePopularity = db.prepare(` UPDATE games SET popularity_score = popularity_score + ? WHERE id = ? `); const processVotes = db.transaction((messages) => { for (const msg of messages) { const { username, message, timestamp } = msg; if (!username || !message || !timestamp) { continue; } // Check for vote patterns let vote = null; if (message.includes('thisgame++')) { vote = 'thisgame++'; } else if (message.includes('thisgame--')) { vote = 'thisgame--'; } // Insert into chat logs insertChatLog.run( req.params.id, username, message, timestamp, vote ); if (vote) { // Find which game was being played at this timestamp const messageTime = new Date(timestamp).getTime(); let matchedGame = null; for (let i = 0; i < sessionGames.length; i++) { const currentGame = sessionGames[i]; const nextGame = sessionGames[i + 1]; const currentGameTime = new Date(currentGame.played_at).getTime(); if (nextGame) { const nextGameTime = new Date(nextGame.played_at).getTime(); if (messageTime >= currentGameTime && messageTime < nextGameTime) { matchedGame = currentGame; break; } } else { // Last game in session if (messageTime >= currentGameTime) { matchedGame = currentGame; break; } } } if (matchedGame) { const points = vote === 'thisgame++' ? 1 : -1; updatePopularity.run(points, matchedGame.game_id); if (!votesByGame[matchedGame.game_id]) { votesByGame[matchedGame.game_id] = { title: matchedGame.title, upvotes: 0, downvotes: 0 }; } if (points > 0) { votesByGame[matchedGame.game_id].upvotes++; } else { votesByGame[matchedGame.game_id].downvotes++; } votesProcessed++; } } } }); processVotes(chatData); res.json({ message: 'Chat log imported and processed successfully', messagesImported: chatData.length, votesProcessed, votesByGame }); } catch (error) { res.status(500).json({ error: error.message }); } }); module.exports = router;