import { NextRequest, NextResponse } from 'next/server' import { auth } from '@/auth' import prisma from '@/lib/prisma' import { notebookOrganizerService } from '@/lib/ai/services/notebook-organizer.service' import { reserveUsageOrThrow, QuotaExceededError } from '@/lib/entitlements' import { syncNoteLabels } from '@/app/actions/notes' export async function POST(request: NextRequest) { try { const session = await auth() if (!session?.user?.id) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } const { notebookId } = await request.json() if (!notebookId) { return NextResponse.json({ error: 'notebookId is required' }, { status: 400 }) } try { await reserveUsageOrThrow(session.user.id, 'reformulate') } catch (err) { if (err instanceof QuotaExceededError) { const isTierLocked = err.currentQuota === 0 return NextResponse.json( { error: isTierLocked ? 'feature_locked' : 'quota_exceeded', errorKey: isTierLocked ? 'ai.featureLocked' : 'ai.quotaExceeded' }, { status: 402 }, ) } throw err } const notes = await prisma.note.findMany({ where: { notebookId, trashedAt: null, userId: session.user.id }, select: { id: true, title: true, content: true }, orderBy: { order: 'asc' }, }) if (notes.length < 2) { return NextResponse.json({ error: 'Need at least 2 notes to organize' }, { status: 400 }) } const notesForAnalysis = notes.map(n => ({ id: n.id, title: n.title || 'Sans titre', contentPreview: n.content.replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim().slice(0, 300), })) const result = await notebookOrganizerService.analyze(notesForAnalysis) return NextResponse.json(result) } catch (error: any) { console.error('[Notebook Organizer] Error:', error) return NextResponse.json({ error: error.message || 'Failed to organize notebook' }, { status: 500 }) } } export async function PATCH(request: NextRequest) { try { const session = await auth() if (!session?.user?.id) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } const { action, tagName, noteIds, notebookId } = await request.json() if (action === 'apply_tag' && tagName && Array.isArray(noteIds)) { // Fetch existing labels for each note, merge with new tag for (const noteId of noteIds) { const note = await prisma.note.findUnique({ where: { id: noteId }, select: { labels: true, notebookId: true }, }) if (!note) continue let existingLabels: string[] = [] try { existingLabels = note.labels ? JSON.parse(note.labels) : [] } catch {} if (!existingLabels.includes(tagName)) { existingLabels.push(tagName) } await syncNoteLabels(noteId, existingLabels, note.notebookId, session.user.id) } return NextResponse.json({ success: true, applied: noteIds.length }) } return NextResponse.json({ error: 'Invalid action' }, { status: 400 }) } catch (error: any) { console.error('[Notebook Organizer PATCH] Error:', error) return NextResponse.json({ error: error.message }, { status: 500 }) } }