import { NextRequest, NextResponse } from "next/server" import prisma from "@/lib/prisma" // Thunderdome vote model and tracking // GET - Get model leaderboard from Thunderdome battles export async function GET(request: NextRequest) { try { const { searchParams } = new URL(request.url) const period = searchParams.get("period") || "all" // all, week, month // Calculate date filter let dateFilter: Date | undefined if (period === "week") { dateFilter = new Date() dateFilter.setDate(dateFilter.getDate() - 7) } else if (period === "month") { dateFilter = new Date() dateFilter.setMonth(dateFilter.getMonth() - 1) } // Get all saved comparisons (thunderdome battles) const whereClause: Record = { type: "thunderdome" } if (dateFilter) { whereClause.createdAt = { gte: dateFilter } } const battles = await prisma.savedComparison.findMany({ where: whereClause, select: { id: true, results: true, winner: true, createdAt: true, }, }) // Aggregate wins and votes by model const modelStats: Record = {} battles.forEach(battle => { const results = battle.results as Array<{ model: string votes: number }> results.forEach(result => { if (!modelStats[result.model]) { modelStats[result.model] = { wins: 0, battles: 0, totalVotes: 0 } } modelStats[result.model].battles += 1 modelStats[result.model].totalVotes += result.votes || 0 if (battle.winner === result.model) { modelStats[result.model].wins += 1 } }) }) // Calculate win rates and sort const leaderboard = Object.entries(modelStats) .map(([model, stats]) => ({ model, wins: stats.wins, battles: stats.battles, totalVotes: stats.totalVotes, winRate: stats.battles > 0 ? (stats.wins / stats.battles) * 100 : 0, })) .sort((a, b) => { // Sort by win rate, then by total battles if (b.winRate !== a.winRate) return b.winRate - a.winRate return b.battles - a.battles }) // Get recent battles for display const recentBattles = await prisma.savedComparison.findMany({ where: { type: "thunderdome" }, orderBy: { createdAt: "desc" }, take: 10, select: { id: true, name: true, prompt: true, results: true, winner: true, createdAt: true, }, }) return NextResponse.json({ leaderboard, recentBattles, totalBattles: battles.length, period, }) } catch (error) { console.error("Error fetching thunderdome stats:", error) return NextResponse.json( { error: "Failed to fetch thunderdome stats" }, { status: 500 } ) } } // POST - Record a community vote on a battle export async function POST(request: NextRequest) { try { const { battleId, modelVote, userId } = await request.json() if (!battleId || !modelVote) { return NextResponse.json( { error: "battleId and modelVote are required" }, { status: 400 } ) } // Get the battle const battle = await prisma.savedComparison.findUnique({ where: { id: battleId }, }) if (!battle) { return NextResponse.json( { error: "Battle not found" }, { status: 404 } ) } // Update the vote count for the model const results = battle.results as Array<{ model: string output: string votes: number }> const updatedResults = results.map(result => { if (result.model === modelVote) { return { ...result, votes: (result.votes || 0) + 1 } } return result }) // Determine new winner const maxVotes = Math.max(...updatedResults.map(r => r.votes || 0)) const newWinner = maxVotes > 0 ? updatedResults.find(r => r.votes === maxVotes)?.model || battle.winner : battle.winner // Update the battle await prisma.savedComparison.update({ where: { id: battleId }, data: { results: updatedResults, winner: newWinner, }, }) return NextResponse.json({ success: true, updatedResults, winner: newWinner, }) } catch (error) { console.error("Error recording vote:", error) return NextResponse.json( { error: "Failed to record vote" }, { status: 500 } ) } }