import { NextRequest, NextResponse } from 'next/server'; import { prisma } from '@/lib/prisma'; import { getCurrentUser } from '@/lib/auth'; // GET - Liste toutes les conversations de l'utilisateur export async function GET(request: NextRequest) { try { const user = await getCurrentUser(); if (!user) { return NextResponse.json({ error: 'Non autorisé' }, { status: 401 }); } const conversations = await prisma.conversation.findMany({ where: { participants: { some: { userId: user.id, }, }, }, include: { participants: { include: { user: { select: { id: true, email: true, name: true, }, }, }, }, messages: { orderBy: { createdAt: 'desc', }, take: 1, include: { sender: { select: { id: true, name: true, email: true, }, }, files: true, }, }, }, orderBy: { updatedAt: 'desc', }, }); // Formater les conversations avec les informations nécessaires const formattedConversations = await Promise.all( conversations.map(async (conv) => { const lastMessage = conv.messages[0] || null; const otherParticipants = conv.participants .filter((p) => p.userId !== user.id) .map((p) => p.user); // Pour les conversations directes, utiliser le nom de l'autre participant const displayName = conv.type === 'group' ? conv.name || 'Groupe sans nom' : otherParticipants[0]?.name || otherParticipants[0]?.email || 'Utilisateur'; // Récupérer lastReadAt pour l'utilisateur actuel const userParticipant = conv.participants.find((p) => p.userId === user.id); const lastReadAt = userParticipant?.lastReadAt || null; // Compter les messages non lus let unreadCount = 0; if (lastMessage && lastReadAt) { const unreadMessages = await prisma.message.count({ where: { conversationId: conv.id, senderId: { not: user.id }, // Exclure les messages de l'utilisateur createdAt: { gt: lastReadAt }, }, }); unreadCount = unreadMessages; } else if (lastMessage && !lastReadAt) { // Si jamais lu, compter tous les messages qui ne sont pas de l'utilisateur const totalUnread = await prisma.message.count({ where: { conversationId: conv.id, senderId: { not: user.id }, }, }); unreadCount = totalUnread; } return { id: conv.id, name: conv.name, type: conv.type, displayName, participants: conv.participants.map((p) => ({ id: p.user.id, email: p.user.email, name: p.user.name, })), lastMessage: lastMessage ? { id: lastMessage.id, content: lastMessage.content, senderId: lastMessage.senderId, senderName: lastMessage.sender.name || lastMessage.sender.email, createdAt: lastMessage.createdAt, hasFiles: lastMessage.files.length > 0, } : null, unreadCount, updatedAt: conv.updatedAt, createdAt: conv.createdAt, }; }) ); return NextResponse.json(formattedConversations); } catch (error) { console.error('Erreur lors de la récupération des conversations:', error); return NextResponse.json({ error: 'Erreur serveur' }, { status: 500 }); } } // POST - Créer une nouvelle conversation export async function POST(request: NextRequest) { try { const user = await getCurrentUser(); if (!user) { return NextResponse.json({ error: 'Non autorisé' }, { status: 401 }); } const body = await request.json(); const { participantIds, name, type } = body; if (!participantIds || !Array.isArray(participantIds) || participantIds.length === 0) { return NextResponse.json( { error: 'Au moins un participant est requis' }, { status: 400 } ); } // Filtrer l'utilisateur actuel de la liste des participants (on ne peut pas créer une conversation avec soi-même) const filteredParticipantIds = participantIds.filter((id: string) => id !== user.id); if (filteredParticipantIds.length === 0) { return NextResponse.json( { error: 'Vous ne pouvez pas créer une conversation avec vous-même' }, { status: 400 } ); } // Vérifier que tous les participants existent const participants = await prisma.user.findMany({ where: { id: { in: filteredParticipantIds, }, }, }); if (participants.length !== filteredParticipantIds.length) { return NextResponse.json( { error: 'Un ou plusieurs participants sont invalides' }, { status: 400 } ); } // Pour les conversations directes, vérifier si une conversation existe déjà if (type === 'direct' && filteredParticipantIds.length === 1) { const existingConversation = await prisma.conversation.findFirst({ where: { type: 'direct', participants: { every: { userId: { in: [user.id, filteredParticipantIds[0]], }, }, }, }, include: { participants: true, }, }); if (existingConversation) { // Vérifier que les deux participants sont bien dans cette conversation const participantUserIds = existingConversation.participants.map((p) => p.userId); if ( participantUserIds.includes(user.id) && participantUserIds.includes(filteredParticipantIds[0]) && participantUserIds.length === 2 ) { return NextResponse.json(existingConversation); } } } // Créer la conversation avec tous les participants (y compris l'utilisateur actuel) const conversation = await prisma.conversation.create({ data: { name: type === 'group' ? name : null, type: type || 'direct', participants: { create: [ { userId: user.id }, ...filteredParticipantIds.map((id: string) => ({ userId: id })), ], }, }, include: { participants: { include: { user: { select: { id: true, email: true, name: true, }, }, }, }, }, }); return NextResponse.json(conversation, { status: 201 }); } catch (error) { console.error('Erreur lors de la création de la conversation:', error); return NextResponse.json({ error: 'Erreur serveur' }, { status: 500 }); } }