/** * GET /api/chats - Lista chats do usuário * POST /api/chats - Cria novo chat */ import { type NextRequest, NextResponse } from "next/server"; import { requireAuth } from "@/lib/auth/middleware"; import { connectMongoDB } from "@/lib/mongodb/connection"; import { Chat } from "@/lib/mongodb/models/Chat"; import { getMainCharacter } from "@/lib/prisma/queries/characters"; import { getListingById } from "@/lib/prisma/queries/listings"; import { getUserById } from "@/lib/prisma/queries/users"; import { secureLogger } from "@/lib/secure-logger"; import { createChatSchema } from "@/lib/validation/chat-schemas"; /** * GET /api/chats * Lista todos os chats do usuário autenticado */ export async function GET(request: NextRequest) { try { const authResult = await requireAuth(request); if (authResult instanceof NextResponse) return authResult; const auth = authResult; await connectMongoDB(); // Buscar todos os chats do usuário (como comprador ou vendedor) const chats = await Chat.find({ $or: [{ buyer_id: auth.userId }, { seller_id: auth.userId }], is_active: true, }) .sort({ updated_at: -1 }) .limit(100); // Serializar datas const serializedChats = chats.map((chat) => ({ chat_id: chat.chat_id, listing_id: chat.listing_id, buyer_id: chat.buyer_id, seller_id: chat.seller_id, created_at: chat.created_at.toISOString(), updated_at: chat.updated_at.toISOString(), last_message_at: chat.last_message_at?.toISOString() || null, last_message_preview: chat.last_message_preview, buyer_unread_count: chat.buyer_unread_count, seller_unread_count: chat.seller_unread_count, is_active: chat.is_active, listing_cache: chat.listing_cache, buyer_cache: chat.buyer_cache, seller_cache: chat.seller_cache, })); return NextResponse.json( { success: true, chats: serializedChats, count: serializedChats.length, }, { status: 200 }, ); } catch (error) { secureLogger.error("❌ Erro ao buscar chats", { error: error instanceof Error ? error.message : "Erro desconhecido", stack: error instanceof Error ? error.stack : undefined, }); return NextResponse.json( { success: false, error: "Erro ao buscar chats" }, { status: 500 }, ); } } /** * POST /api/chats * Cria um novo chat entre comprador e vendedor */ export async function POST(request: NextRequest) { try { const authResult = await requireAuth(request); if (authResult instanceof NextResponse) return authResult; const auth = authResult; const body = await request.json(); const validationResult = createChatSchema.safeParse(body); if (!validationResult.success) { return NextResponse.json( { success: false, error: "Dados inválidos", details: validationResult.error.issues, }, { status: 400 }, ); } const { listing_id, buyer_message } = validationResult.data; await connectMongoDB(); // Buscar anúncio const listing = await getListingById(listing_id); if (!listing) { return NextResponse.json( { success: false, error: "Anúncio não encontrado" }, { status: 404 }, ); } // Verificar se não é o próprio vendedor if (listing.seller_id === auth.userId) { return NextResponse.json( { success: false, error: "Você não pode criar um chat com você mesmo" }, { status: 400 }, ); } // Verificar se anúncio está ativo if (listing.listing_status !== "active") { return NextResponse.json( { success: false, error: "Anúncio não está disponível para chat" }, { status: 400 }, ); } // Gerar chat_id único const chat_id = `${listing_id}_${auth.userId}_${listing.seller_id}`; // Verificar se chat já existe let chat = await Chat.findOne({ chat_id }); if (chat) { // Chat já existe, retornar return NextResponse.json( { success: true, chat: { chat_id: chat.chat_id, listing_id: chat.listing_id, buyer_id: chat.buyer_id, seller_id: chat.seller_id, created_at: chat.created_at.toISOString(), updated_at: chat.updated_at.toISOString(), last_message_at: chat.last_message_at?.toISOString() || null, last_message_preview: chat.last_message_preview, buyer_unread_count: chat.buyer_unread_count, seller_unread_count: chat.seller_unread_count, is_active: chat.is_active, listing_cache: chat.listing_cache, buyer_cache: chat.buyer_cache, seller_cache: chat.seller_cache, }, already_exists: true, }, { status: 200 }, ); } // Buscar dados do comprador const buyer = await getUserById(auth.userId); if (!buyer) { return NextResponse.json( { success: false, error: "Usuário não encontrado" }, { status: 404 }, ); } const buyerCharacter = await getMainCharacter(auth.userId); // Buscar dados do vendedor const seller = await getUserById(listing.seller_id); if (!seller) { return NextResponse.json( { success: false, error: "Vendedor não encontrado" }, { status: 404 }, ); } const sellerCharacter = await getMainCharacter(listing.seller_id); // Criar chat chat = new Chat({ chat_id, listing_id, buyer_id: auth.userId, seller_id: listing.seller_id, listing_cache: { item_name: listing.item_name, item_image_url: null, // Imagem será obtida via item_id se necessário price_pix: listing.price_pix ? Number(listing.price_pix) : null, price_tibia_coins: listing.price_tibia_coins || null, price_gold_coins: listing.price_gold_coins ? Number(listing.price_gold_coins) : null, 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(); // Se houver mensagem inicial, criar if (buyer_message && buyer_message.trim().length > 0) { const { Message } = await import("@/lib/mongodb/models/Message"); const message = new Message({ chat_id, sender_id: auth.userId, content: buyer_message.trim(), message_type: "text", }); await message.save(); // Atualizar chat chat.last_message_at = new Date(); chat.last_message_preview = buyer_message.substring(0, 100); chat.seller_unread_count = 1; await chat.save(); } return NextResponse.json( { success: true, chat: { chat_id: chat.chat_id, listing_id: chat.listing_id, buyer_id: chat.buyer_id, seller_id: chat.seller_id, created_at: chat.created_at.toISOString(), updated_at: chat.updated_at.toISOString(), last_message_at: chat.last_message_at?.toISOString() || null, last_message_preview: chat.last_message_preview, buyer_unread_count: chat.buyer_unread_count, seller_unread_count: chat.seller_unread_count, is_active: chat.is_active, listing_cache: chat.listing_cache, buyer_cache: chat.buyer_cache, seller_cache: chat.seller_cache, }, already_exists: false, }, { status: 201 }, ); } catch (error) { secureLogger.error("❌ Erro ao criar chat", { error: error instanceof Error ? error.message : "Erro desconhecido", stack: error instanceof Error ? error.stack : undefined, }); return NextResponse.json( { success: false, error: "Erro ao criar chat" }, { status: 500 }, ); } }