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

async function upsertLeaderboardEntry(userId, grade, subject, sessionScore, correctAnswers) {
  const existing = await db.leaderboardEntry.findUnique({
    where: { userId_grade_subject: { userId, grade, subject } },
  });

  return db.leaderboardEntry.upsert({
    where: { userId_grade_subject: { userId, grade, subject } },
    create: {
      userId,
      grade,
      subject,
      bestScore: sessionScore,
      gamesPlayed: 1,
      totalCorrect: correctAnswers,
    },
    update: {
      bestScore: existing && sessionScore > existing.bestScore ? sessionScore : undefined,
      gamesPlayed: { increment: 1 },
      totalCorrect: { increment: correctAnswers },
    },
  });
}

async function getLeaderboard(grade, subject, limit = 50) {
  const entries = await db.leaderboardEntry.findMany({
    where: { grade, subject },
    orderBy: [{ bestScore: 'desc' }, { totalCorrect: 'desc' }],
    take: limit,
    include: {
      user: { select: { displayName: true, avatarUrl: true } },
    },
  });

  return entries.map((entry, index) => ({ ...entry, rank: index + 1 }));
}

async function getUserRank(userId, grade, subject) {
  const entry = await db.leaderboardEntry.findUnique({
    where: { userId_grade_subject: { userId, grade, subject } },
  });

  if (!entry) return null;

  const rank =
    (await db.leaderboardEntry.count({
      where: {
        grade,
        subject,
        OR: [
          { bestScore: { gt: entry.bestScore } },
          { bestScore: entry.bestScore, totalCorrect: { gt: entry.totalCorrect } },
        ],
      },
    })) + 1;

  return { rank, entry };
}

module.exports = { upsertLeaderboardEntry, getLeaderboard, getUserRank };
