import { NextRequest, NextResponse } from 'next/server'; import { prisma } from '@/lib/prisma'; import { getCurrentUser } from '@/lib/auth'; import { writeFile } from 'fs/promises'; import { join } from 'path'; import { existsSync, mkdirSync } from 'fs'; // GET - Récupérer les messages d'une conversation export async function GET( request: NextRequest, { params }: { params: { id: string } } ) { try { const user = await getCurrentUser(); if (!user) { return NextResponse.json({ error: 'Non autorisé' }, { status: 401 }); } const searchParams = request.nextUrl.searchParams; const limit = parseInt(searchParams.get('limit') || '50'); const cursor = searchParams.get('cursor'); const conversation = await prisma.conversation.findUnique({ where: { id: params.id }, include: { participants: true, }, }); if (!conversation) { return NextResponse.json({ error: 'Conversation non trouvée' }, { status: 404 }); } // Vérifier que l'utilisateur est participant const isParticipant = conversation.participants.some((p) => p.userId === user.id); if (!isParticipant) { return NextResponse.json({ error: 'Accès non autorisé' }, { status: 403 }); } // Mettre à jour lastReadAt pour l'utilisateur await prisma.conversationParticipant.updateMany({ where: { conversationId: params.id, userId: user.id, }, data: { lastReadAt: new Date(), }, }); const where: any = { conversationId: params.id, }; if (cursor) { where.id = { lt: cursor, }; } const messages = await prisma.message.findMany({ where, include: { sender: { select: { id: true, email: true, name: true, }, }, files: true, }, orderBy: { createdAt: 'desc', }, take: limit, }); return NextResponse.json({ messages: messages.reverse(), // Inverser pour avoir les plus anciens en premier hasMore: messages.length === limit, cursor: messages.length > 0 ? messages[0].id : null, }); } catch (error) { console.error('Erreur lors de la récupération des messages:', error); return NextResponse.json({ error: 'Erreur serveur' }, { status: 500 }); } } // POST - Envoyer un message dans une conversation export async function POST( request: NextRequest, { params }: { params: { id: string } } ) { try { const user = await getCurrentUser(); if (!user) { return NextResponse.json({ error: 'Non autorisé' }, { status: 401 }); } const conversation = await prisma.conversation.findUnique({ where: { id: params.id }, include: { participants: true, }, }); if (!conversation) { return NextResponse.json({ error: 'Conversation non trouvée' }, { status: 404 }); } // Vérifier que l'utilisateur est participant const isParticipant = conversation.participants.some((p) => p.userId === user.id); if (!isParticipant) { return NextResponse.json({ error: 'Accès non autorisé' }, { status: 403 }); } const formData = await request.formData(); const content = formData.get('content') as string | null; const files = formData.getAll('files') as File[]; if (!content && (!files || files.length === 0)) { return NextResponse.json( { error: 'Le message doit contenir du texte ou au moins un fichier' }, { status: 400 } ); } // Créer le message const message = await prisma.message.create({ data: { conversationId: params.id, senderId: user.id, content: content || null, }, include: { sender: { select: { id: true, email: true, name: true, }, }, files: true, }, }); // Traiter les fichiers si présents if (files && files.length > 0) { const uploadDir = join(process.cwd(), 'public', 'uploads', 'messages'); // Créer le dossier s'il n'existe pas if (!existsSync(uploadDir)) { mkdirSync(uploadDir, { recursive: true }); } const fileRecords = await Promise.all( files.map(async (file) => { const bytes = await file.arrayBuffer(); const buffer = Buffer.from(bytes); // Générer un nom de fichier unique const timestamp = Date.now(); const randomStr = Math.random().toString(36).substring(2, 15); const fileExtension = file.name.split('.').pop(); const filename = `${timestamp}-${randomStr}.${fileExtension}`; const filepath = join(uploadDir, filename); // Sauvegarder le fichier await writeFile(filepath, buffer); // Créer l'enregistrement en base de données return prisma.messageFile.create({ data: { messageId: message.id, filename: file.name, filepath: `/uploads/messages/${filename}`, fileType: file.type, fileSize: file.size, }, }); }) ); // Récupérer le message avec les fichiers const messageWithFiles = await prisma.message.findUnique({ where: { id: message.id }, include: { sender: { select: { id: true, email: true, name: true, }, }, files: true, }, }); // Mettre à jour la date de mise à jour de la conversation await prisma.conversation.update({ where: { id: params.id }, data: { updatedAt: new Date() }, }); return NextResponse.json(messageWithFiles, { status: 201 }); } // Mettre à jour la date de mise à jour de la conversation await prisma.conversation.update({ where: { id: params.id }, data: { updatedAt: new Date() }, }); return NextResponse.json(message, { status: 201 }); } catch (error) { console.error('Erreur lors de l\'envoi du message:', error); return NextResponse.json({ error: 'Erreur serveur' }, { status: 500 }); } }