/** * Funções para criar mensagens do sistema no chat */ import { connectMongoDB } from "@/lib/mongodb/connection"; import { Chat } from "@/lib/mongodb/models/Chat"; import { Message } from "@/lib/mongodb/models/Message"; import { secureLogger } from "@/lib/secure-logger"; import { getSocketIO } from "@/lib/socket/server"; interface CreateSystemMessageParams { listingId: number; buyerId: number; sellerId: number; message: string; metadata?: { action?: string; [key: string]: any; }; } /** * Cria uma mensagem do sistema no chat e notifica os participantes */ export async function createSystemMessageInChat( params: CreateSystemMessageParams, ): Promise { try { await connectMongoDB(); // Gerar chat_id (mesmo formato usado na criação de chat) const chatId = `${params.listingId}_${params.buyerId}_${params.sellerId}`; // Buscar ou criar chat let chat = await Chat.findOne({ chat_id: chatId }); if (!chat) { // Se o chat não existe, criar (isso pode acontecer se a intenção foi criada antes do chat) // Buscar dados do listing para cache const { getListingById } = await import("@/lib/prisma/queries/listings"); const listing = await getListingById(params.listingId); if (!listing) { throw new Error("Listing não encontrado"); } // Buscar dados dos usuários const { getUserById } = await import("@/lib/prisma/queries/users"); const buyer = await getUserById(params.buyerId); const seller = await getUserById(params.sellerId); if (!buyer || !seller) { throw new Error("Usuário não encontrado"); } // Buscar personagem principal do comprador e vendedor const { getMainCharacter } = await import( "@/lib/prisma/queries/characters" ); const buyerCharacter = await getMainCharacter(params.buyerId); const sellerCharacter = await getMainCharacter(params.sellerId); chat = new Chat({ chat_id: chatId, listing_id: params.listingId, buyer_id: params.buyerId, seller_id: params.sellerId, is_active: true, buyer_unread_count: 0, seller_unread_count: 1, // Vendedor será notificado listing_cache: { item_name: listing.item_name, item_image_url: null, // Pode ser preenchido depois se necessário price_pix: listing.price_pix ? Number(listing.price_pix) : undefined, price_tibia_coins: listing.price_tibia_coins || undefined, price_gold_coins: listing.price_gold_coins ? Number(listing.price_gold_coins) : undefined, server_name: listing.server_name, listing_status: listing.listing_status, }, buyer_cache: { user_id: buyer.user_id, username: buyer.username, character_name: buyerCharacter?.character_name || null, }, seller_cache: { user_id: seller.user_id, username: seller.username, character_name: sellerCharacter?.character_name || null, }, }); await chat.save(); } // Criar mensagem do sistema const systemMessage = new Message({ chat_id: chatId, sender_id: 0, // 0 = sistema content: params.message, message_type: "system", metadata: params.metadata || {}, }); await systemMessage.save(); // Atualizar chat chat.last_message_at = new Date(); chat.last_message_preview = params.message.substring(0, 100); chat.seller_unread_count += 1; // Notificar vendedor await chat.save(); // Emitir mensagem via Socket.io para participantes do chat const io = getSocketIO(); if (io) { io.to(`chat:${chatId}`).emit("new_message", { message: { _id: systemMessage._id.toString(), chat_id: systemMessage.chat_id, sender_id: 0, content: systemMessage.content, created_at: systemMessage.created_at.toISOString(), read_at: null, message_type: "system", metadata: systemMessage.metadata, }, }); } secureLogger.info("✅ Mensagem do sistema criada no chat", { chatId, message: params.message, action: params.metadata?.action, }); } catch (error) { secureLogger.error("❌ Erro ao criar mensagem do sistema no chat", { error: error instanceof Error ? error.message : "Erro desconhecido", stack: error instanceof Error ? error.stack : undefined, }); throw error; } }