import { NextRequest, NextResponse } from "next/server"; import { secureLogger } from "@/lib/secure-logger"; import { requireAuth } from "@/lib/auth/middleware"; import { getListingById } from "@/lib/prisma/queries/listings"; import { createNotification } from "@/lib/prisma/queries/notifications"; import { createPurchaseIntention, hasPendingIntention, } from "@/lib/prisma/queries/purchase-intentions"; import { trackEvent } from "@/lib/prisma/queries/telemetry"; /** * POST /api/listings/[id]/purchase * Cria uma intenção de compra para um item anunciado */ export async function POST( request: NextRequest, { params }: { params: { id: string } } ) { try { const authResult = await requireAuth(request); if (authResult instanceof NextResponse) return authResult; const auth = authResult; const listingId = parseInt(params.id, 10); if (isNaN(listingId)) { return NextResponse.json( { success: false, error: "ID de anúncio inválido" }, { status: 400 } ); } const body = await request.json(); const { payment_method, buyer_message } = body; // 'pix' | 'tc' | 'gp' | 'trade' if (!payment_method) { return NextResponse.json( { success: false, error: "Método de pagamento é obrigatório" }, { status: 400 } ); } // Buscar listing const listing = await getListingById(listingId); if (!listing) { return NextResponse.json( { success: false, error: "Anúncio não encontrado" }, { status: 404 } ); } // Validar se não é o vendedor if (listing.seller_id === auth.userId) { return NextResponse.json( { success: false, error: "Você não pode comprar seu próprio anúncio" }, { status: 403 } ); } // Validar se está ativo if (listing.listing_status !== "active") { return NextResponse.json( { success: false, error: "Anúncio não está disponível para compra" }, { status: 400 } ); } // Validar se é leilão (leilões não podem ser comprados diretamente, apenas com lances) if (listing.is_auction) { return NextResponse.json( { success: false, error: "Este item está em leilão. Use a funcionalidade de lance." }, { status: 400 } ); } // Validar método de pagamento disponível const availableMethods: string[] = []; if (listing.price_pix) availableMethods.push("pix"); if (listing.price_tibia_coins) availableMethods.push("tibia_coins"); if (listing.price_gold_coins) availableMethods.push("gold_coins"); if (listing.trade_item_id) availableMethods.push("trade"); // Normalizar método de pagamento let normalizedMethod = payment_method; if (payment_method === "tc") normalizedMethod = "tibia_coins"; if (payment_method === "gp") normalizedMethod = "gold_coins"; if (!availableMethods.includes(normalizedMethod)) { return NextResponse.json( { success: false, error: `Método de pagamento "${payment_method}" não está disponível para este anúncio`, available_methods: availableMethods, }, { status: 400 } ); } // Verificar se já existe uma intenção pendente const alreadyHasPending = await hasPendingIntention(listingId, auth.userId); if (alreadyHasPending) { return NextResponse.json( { success: false, error: "Você já possui uma intenção de compra pendente para este anúncio" }, { status: 400 } ); } // Criar intenção de compra ao invés de mudar status diretamente const intention = await createPurchaseIntention({ listing_id: listingId, buyer_id: auth.userId, payment_method: normalizedMethod as any, buyer_message: buyer_message || undefined, }); // Criar notificação para o vendedor await createNotification({ user_id: listing.seller_id, notification_type: "purchase", title: "Nova intenção de compra!", message: `Alguém manifestou interesse em comprar seu item "${listing.item_name}" por ${normalizedMethod.toUpperCase()}`, related_id: listingId, send_whatsapp: false, }); // Registrar telemetria await trackEvent({ event_type: "purchase_intention_created", ad_id: listingId, user_id: auth.userId, metadata: { payment_method: normalizedMethod, listing_price_pix: listing.price_pix ? Number(listing.price_pix) : null, listing_price_tc: listing.price_tibia_coins || null, listing_price_gp: listing.price_gold_coins ? Number(listing.price_gold_coins) : null, }, }); secureLogger.info("✅ Intenção de compra criada com sucesso", { userId: auth.userId, listingId, intentionId: intention.intention_id, paymentMethod: normalizedMethod, }); return NextResponse.json( { success: true, intention, message: "Intenção de compra criada com sucesso. O vendedor será notificado.", }, { status: 201 } ); } catch (error) { secureLogger.error("❌ Erro ao criar intenção de compra", { error: error instanceof Error ? error.message : "Erro desconhecido", stack: error instanceof Error ? error.stack : undefined, }); return NextResponse.json( { success: false, error: "Erro ao criar intenção de compra" }, { status: 500 } ); } }