import { NextResponse } from 'next/server' import { getUserFromToken } from '@/lib/auth' import { prisma } from '@/lib/db' export const runtime = 'nodejs' /** * GET /api/user/reading-plans/[id]/progress * Get progress for a specific reading plan */ export async function GET( request: Request, { params }: { params: Promise<{ id: string }> } ) { try { const { id } = await params // Get token from authorization header const authHeader = request.headers.get('authorization') const token = authHeader?.replace('Bearer ', '') if (!token) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } // Verify token and get user const user = await getUserFromToken(token) if (!user) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } // Verify plan belongs to user const userPlan = await prisma.userReadingPlan.findUnique({ where: { id, userId: user.id } }) if (!userPlan) { return NextResponse.json( { error: 'Reading plan not found' }, { status: 404 } ) } const progress = await prisma.userReadingProgress.findMany({ where: { userPlanId: id, userId: user.id }, orderBy: { planDay: 'asc' } }) return NextResponse.json({ success: true, progress }) } catch (error) { console.error('Reading progress fetch error:', error) return NextResponse.json( { error: 'Failed to fetch reading progress' }, { status: 500 } ) } } /** * POST /api/user/reading-plans/[id]/progress * Mark a reading as complete */ export async function POST( request: Request, { params }: { params: Promise<{ id: string }> } ) { try { const { id } = await params // Get token from authorization header const authHeader = request.headers.get('authorization') const token = authHeader?.replace('Bearer ', '') if (!token) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } // Verify token and get user const user = await getUserFromToken(token) if (!user) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } const body = await request.json() const { planDay, bookId, chapterNum, versesRead, completed, notes } = body // Validate required fields if (!planDay || !bookId || !chapterNum) { return NextResponse.json( { error: 'planDay, bookId, and chapterNum are required' }, { status: 400 } ) } // Verify plan belongs to user const userPlan = await prisma.userReadingPlan.findUnique({ where: { id, userId: user.id } }) if (!userPlan) { return NextResponse.json( { error: 'Reading plan not found' }, { status: 404 } ) } // Create or update progress entry const progress = await prisma.userReadingProgress.upsert({ where: { userPlanId_planDay_bookId_chapterNum: { userPlanId: id, planDay: parseInt(planDay), bookId: bookId, chapterNum: parseInt(chapterNum) } }, create: { userId: user.id, userPlanId: id, planDay: parseInt(planDay), bookId: bookId, chapterNum: parseInt(chapterNum), versesRead: versesRead || null, completed: completed !== false, notes: notes || null }, update: { completed: completed !== false, versesRead: versesRead || null, notes: notes || null, updatedAt: new Date() } }) // Update user plan statistics if (completed !== false) { // Count total completed days const completedDays = await prisma.userReadingProgress.count({ where: { userPlanId: id, userId: user.id, completed: true } }) // Calculate streak const allProgress = await prisma.userReadingProgress.findMany({ where: { userPlanId: id, userId: user.id, completed: true }, orderBy: { date: 'desc' }, select: { date: true } }) let currentStreak = 0 let longestStreak = 0 let tempStreak = 0 let lastDate: Date | null = null for (const entry of allProgress) { if (!lastDate) { tempStreak = 1 lastDate = new Date(entry.date) } else { const dayDiff = Math.floor((lastDate.getTime() - new Date(entry.date).getTime()) / (1000 * 60 * 60 * 24)) if (dayDiff === 1) { tempStreak++ } else { if (tempStreak > longestStreak) { longestStreak = tempStreak } tempStreak = 1 } lastDate = new Date(entry.date) } } currentStreak = tempStreak if (currentStreak > longestStreak) { longestStreak = currentStreak } // Update current day if this is the latest completed day const maxDay = parseInt(planDay) const shouldUpdateCurrentDay = maxDay >= userPlan.currentDay await prisma.userReadingPlan.update({ where: { id }, data: { completedDays: completedDays, streak: currentStreak, longestStreak: Math.max(longestStreak, userPlan.longestStreak), ...(shouldUpdateCurrentDay && { currentDay: maxDay + 1 }) } }) } return NextResponse.json({ success: true, message: 'Reading progress updated successfully', progress }) } catch (error) { console.error('Reading progress update error:', error) return NextResponse.json( { error: 'Failed to update reading progress' }, { status: 500 } ) } }