import { NextResponse } from 'next/server'; import { prisma } from '@/lib/db'; import { getCurrentAdmin, AdminPermission, hasPermission } from '@/lib/admin-auth'; export const runtime = 'nodejs'; export async function GET(request: Request) { try { const admin = await getCurrentAdmin(request as any); if (!admin || !hasPermission(admin, AdminPermission.READ_ANALYTICS)) { return NextResponse.json( { error: 'Unauthorized' }, { status: 401 } ); } const url = new URL(request.url); const period = url.searchParams.get('period') || '30'; // days const periodDays = parseInt(period); const startDate = new Date(); startDate.setDate(startDate.getDate() - periodDays); // Prayer request engagement const prayerRequestEngagement = await prisma.prayerRequest.findMany({ select: { id: true, title: true, category: true, author: true, prayerCount: true, createdAt: true, isActive: true, _count: { select: { prayers: true, userPrayers: true } } }, where: { createdAt: { gte: startDate } }, orderBy: { prayerCount: 'desc' }, take: 50 }); // Prayer request engagement timeline const prayerEngagementTimeline = await Promise.all( Array.from({ length: periodDays }, (_, i) => { const date = new Date(); date.setDate(date.getDate() - i); return date.toISOString().split('T')[0]; }).reverse().map(async (date) => { const startOfDay = new Date(date + 'T00:00:00.000Z'); const endOfDay = new Date(date + 'T23:59:59.999Z'); const [newRequests, newPrayers] = await Promise.all([ prisma.prayerRequest.count({ where: { createdAt: { gte: startOfDay, lte: endOfDay } } }), prisma.prayer.count({ where: { createdAt: { gte: startOfDay, lte: endOfDay } } }) ]); return { date, newRequests, newPrayers }; }) ); // Chat conversation engagement const chatEngagement = await prisma.chatConversation.findMany({ select: { id: true, title: true, language: true, createdAt: true, lastMessageAt: true, isActive: true, _count: { select: { messages: true } } }, where: { createdAt: { gte: startDate } }, orderBy: { lastMessageAt: 'desc' }, take: 50 }); // Most bookmarked verses const mostBookmarkedVerses = await prisma.bookmark.groupBy({ by: ['verseId'], _count: { verseId: true }, where: { createdAt: { gte: startDate } }, orderBy: { _count: { verseId: 'desc' } }, take: 20 }); // Get verse details for bookmarked verses const verseDetails = await Promise.all( mostBookmarkedVerses.map(async (bookmark) => { const verse = await prisma.bibleVerse.findUnique({ where: { id: bookmark.verseId }, select: { id: true, verseNum: true, text: true, chapter: { select: { chapterNum: true, book: { select: { name: true } } } } } }); return { ...bookmark, verse }; }) ); // Content categories performance const categoryPerformance = await prisma.prayerRequest.groupBy({ by: ['category'], _sum: { prayerCount: true }, _count: { category: true }, _avg: { prayerCount: true }, where: { createdAt: { gte: startDate }, isActive: true } }); // Language distribution for conversations const languageDistribution = await prisma.chatConversation.groupBy({ by: ['language'], _count: { language: true }, where: { createdAt: { gte: startDate } } }); // Content creation vs engagement ratio const contentMetrics = { totalPrayerRequests: await prisma.prayerRequest.count({ where: { createdAt: { gte: startDate } } }), totalPrayers: await prisma.prayer.count({ where: { createdAt: { gte: startDate } } }), totalConversations: await prisma.chatConversation.count({ where: { createdAt: { gte: startDate } } }), totalMessages: await prisma.chatMessage.count({ where: { timestamp: { gte: startDate } } }), totalBookmarks: await prisma.bookmark.count({ where: { createdAt: { gte: startDate } } }) }; // Average engagement rates const avgPrayersPerRequest = contentMetrics.totalPrayerRequests > 0 ? contentMetrics.totalPrayers / contentMetrics.totalPrayerRequests : 0; const avgMessagesPerConversation = contentMetrics.totalConversations > 0 ? contentMetrics.totalMessages / contentMetrics.totalConversations : 0; // Content quality metrics (based on engagement) const highEngagementRequests = prayerRequestEngagement.filter(req => req.prayerCount >= 5).length; const lowEngagementRequests = prayerRequestEngagement.filter(req => req.prayerCount <= 1).length; const engagementDistribution = { high: highEngagementRequests, medium: prayerRequestEngagement.length - highEngagementRequests - lowEngagementRequests, low: lowEngagementRequests }; return NextResponse.json({ period: periodDays, engagement: { prayerRequests: prayerRequestEngagement.slice(0, 20), conversations: chatEngagement.slice(0, 20), bookmarkedVerses: verseDetails.slice(0, 15) }, timeline: { prayers: prayerEngagementTimeline }, metrics: { ...contentMetrics, avgPrayersPerRequest: Math.round(avgPrayersPerRequest * 100) / 100, avgMessagesPerConversation: Math.round(avgMessagesPerConversation * 100) / 100 }, distributions: { categories: categoryPerformance, languages: languageDistribution, engagement: engagementDistribution } }); } catch (error) { console.error('Admin content analytics error:', error); return NextResponse.json( { error: 'Server error' }, { status: 500 } ); } }