const express = require('express');
const db = require('../database');

const router = express.Router();

/**
 * Select a game using weighted random selection based on favor bias
 * 
 * Bias system:
 * - favor_bias = 1 (favored): 3x weight
 * - favor_bias = 0 (neutral): 1x weight
 * - favor_bias = -1 (disfavored): 0.2x weight (still possible but less likely)
 * 
 * Also considers pack-level bias
 */
function selectGameWithBias(games) {
  if (games.length === 0) return null;
  if (games.length === 1) return games[0];

  // Get pack biases
  const packs = db.prepare('SELECT name, favor_bias FROM packs').all();
  const packBiasMap = {};
  packs.forEach(pack => {
    packBiasMap[pack.name] = pack.favor_bias || 0;
  });

  // Calculate weights for each game
  const weights = games.map(game => {
    let weight = 1.0; // Base weight

    // Apply game-level bias
    const gameBias = game.favor_bias || 0;
    if (gameBias === 1) {
      weight *= 3.0; // Favored games are 3x more likely
    } else if (gameBias === -1) {
      weight *= 0.2; // Disfavored games are 5x less likely
    }

    // Apply pack-level bias
    const packBias = packBiasMap[game.pack_name] || 0;
    if (packBias === 1) {
      weight *= 2.0; // Favored packs are 2x more likely
    } else if (packBias === -1) {
      weight *= 0.3; // Disfavored packs are ~3x less likely
    }

    return weight;
  });

  // Calculate total weight
  const totalWeight = weights.reduce((sum, w) => sum + w, 0);

  // Pick a random number between 0 and totalWeight
  let random = Math.random() * totalWeight;

  // Select game based on weighted random
  for (let i = 0; i < games.length; i++) {
    random -= weights[i];
    if (random <= 0) {
      return games[i];
    }
  }

  // Fallback (shouldn't reach here)
  return games[games.length - 1];
}

// Pick a random game with filters and repeat avoidance
router.post('/pick', (req, res) => {
  try {
    const {
      playerCount,
      drawing,
      length,
      familyFriendly,
      sessionId,
      excludePlayed
    } = req.body;

    // Build query for eligible games
    let query = 'SELECT * FROM games WHERE enabled = 1';
    const params = [];

    if (playerCount) {
      const count = parseInt(playerCount);
      query += ' AND min_players <= ? AND max_players >= ?';
      params.push(count, count);
    }

    if (drawing === 'only') {
      query += ' AND game_type = ?';
      params.push('Drawing');
    } else if (drawing === 'exclude') {
      query += ' AND (game_type != ? OR game_type IS NULL)';
      params.push('Drawing');
    }

    if (length) {
      if (length === 'short') {
        query += ' AND (length_minutes <= 15 OR length_minutes IS NULL)';
      } else if (length === 'medium') {
        query += ' AND length_minutes > 15 AND length_minutes <= 25';
      } else if (length === 'long') {
        query += ' AND length_minutes > 25';
      }
    }

    if (familyFriendly !== undefined) {
      query += ' AND family_friendly = ?';
      params.push(familyFriendly ? 1 : 0);
    }

    // Get eligible games
    const stmt = db.prepare(query);
    let eligibleGames = stmt.all(...params);

    if (eligibleGames.length === 0) {
      return res.status(404).json({ 
        error: 'No games match the current filters',
        suggestion: 'Try adjusting your filters or enabling more games'
      });
    }

    // Apply repeat avoidance if session provided
    if (sessionId) {
      let lastGamesQuery;
      
      if (excludePlayed) {
        // Exclude ALL previously played games in this session
        lastGamesQuery = db.prepare(`
          SELECT DISTINCT game_id FROM session_games
          WHERE session_id = ?
        `).all(sessionId);
      } else {
        // Default: only exclude last 2 games
        lastGamesQuery = db.prepare(`
          SELECT game_id FROM session_games
          WHERE session_id = ?
          ORDER BY played_at DESC
          LIMIT 2
        `).all(sessionId);
      }

      const excludeIds = lastGamesQuery.map(g => g.game_id);
      
      if (excludeIds.length > 0) {
        eligibleGames = eligibleGames.filter(game => !excludeIds.includes(game.id));
      }

      if (eligibleGames.length === 0) {
        return res.status(404).json({
          error: excludePlayed 
            ? 'All eligible games have been played in this session' 
            : 'All eligible games have been played recently',
          suggestion: 'Enable more games or adjust your filters',
          recentlyPlayed: excludeIds
        });
      }
    }

    // Apply favor biasing to selection
    const selectedGame = selectGameWithBias(eligibleGames);

    res.json({
      game: selectedGame,
      poolSize: eligibleGames.length,
      totalEnabled: eligibleGames.length + (sessionId ? 2 : 0) // Approximate
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

module.exports = router;

