import { NextRequest, NextResponse } from 'next/server'; import { db, habits, users, habitLogs } from '@/lib/db'; import { getTokenCookie } from '@/lib/auth/cookies'; import { eq, and, desc } from 'drizzle-orm'; async function getUserFromToken() { const token = await getTokenCookie(); if (!token) return null; const userRows = await db.select().from(users).where(eq(users.token, token)); return userRows.length > 0 ? userRows[0] : null; } export async function GET() { try { const user = await getUserFromToken(); if (!user) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } // Get current timestamp for date calculations const now = new Date(); const sevenDaysAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000); const thirtyDaysAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000); // First get all habits const userHabitsBase = await db .select() .from(habits) .where(and(eq(habits.userId, user.id), eq(habits.isArchived, false))) .orderBy(desc(habits.createdAt)); // Then get aggregated log data for each habit const habitsWithStats = await Promise.all( userHabitsBase.map(async (habit) => { // Get all logs for this habit const logs = await db .select({ loggedAt: habitLogs.loggedAt, }) .from(habitLogs) .where(eq(habitLogs.habitId, habit.id)); // Calculate statistics const totalLogs = logs.length; const logsLastWeek = logs.filter((log) => log.loggedAt >= sevenDaysAgo).length; const logsLastMonth = logs.filter((log) => log.loggedAt >= thirtyDaysAgo).length; const lastLoggedAt = logs.length > 0 ? logs.reduce( (latest, log) => (log.loggedAt > latest ? log.loggedAt : latest), logs[0].loggedAt, ) : null; return { id: habit.id, name: habit.name, type: habit.type, targetFrequency: habit.targetFrequency, color: habit.color, icon: habit.icon, createdAt: habit.createdAt, lastLoggedAt, totalLogs, logsLastWeek, logsLastMonth, }; }), ); return NextResponse.json({ habits: habitsWithStats }); } catch (error) { console.error('Get habits error:', error); return NextResponse.json({ error: 'Internal server error' }, { status: 500 }); } } export async function POST(request: NextRequest) { try { const user = await getUserFromToken(); if (!user) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const body = (await request.json()) as { name: string; type: string; targetFrequency?: { value: number; period: 'day' | 'week' | 'month' }; color?: string; icon?: string; }; const { name, type, targetFrequency, color, icon } = body; if (!name || !type) { return NextResponse.json( { error: 'Name and type are required', }, { status: 400 }, ); } // Validate type is one of the allowed enum values if (!['positive', 'neutral', 'negative'].includes(type)) { return NextResponse.json( { error: 'Type must be one of: positive, neutral, negative', }, { status: 400 }, ); } const newHabitRows = await db .insert(habits) .values({ userId: user.id, name, type: type as 'positive' | 'neutral' | 'negative', targetFrequency, color, icon, }) .returning(); if (newHabitRows.length === 0) { throw new Error('Failed to create habit'); } const newHabit = newHabitRows[0]; return NextResponse.json({ habit: newHabit }); } catch (error) { console.error('Create habit error:', error); return NextResponse.json({ error: 'Internal server error' }, { status: 500 }); } }