"use client"; import { useQueryClient } from "@tanstack/react-query"; import { CheckCircle2, Clock, Loader2, MessageSquare, ShoppingBag, ShoppingCart, User, XCircle, } from "lucide-react"; import { useEffect, useState } from "react"; import { Avatar, AvatarFallback } from "@/components/ui/avatar"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Label } from "@/components/ui/label"; import { Separator } from "@/components/ui/separator"; import { Textarea } from "@/components/ui/textarea"; import { useSession } from "@/lib/hooks/use-session"; interface PurchaseIntention { intention_id: number; buyer_id: number; payment_method: string; status: "pending" | "accepted" | "rejected" | "expired" | "completed"; buyer_message: string | null; seller_response: string | null; created_at: string; custom_offer_amount: number | null; custom_offer_currency: string | null; custom_offer_created_at: string | null; buyer?: { user_id: number; username: string; email: string; }; } interface IntentionDetailModalProps { open: boolean; onOpenChange: (open: boolean) => void; intention: PurchaseIntention; listingId: number; onUpdate?: () => void; } function getPaymentMethodLabel(method: string): string { switch (method) { case "pix": return "PIX"; case "tibia_coins": return "Tibia Coins"; case "gold_coins": return "Gold Coins"; case "trade": return "Troca"; default: return method.toUpperCase(); } } function getStatusBadge(status: string) { switch (status) { case "pending": return ( Pendente ); case "accepted": return ( Aceita ); case "rejected": return ( Rejeitada ); default: return {status}; } } function formatCustomOffer( intention: PurchaseIntention, ): { value: string; date: string | null } | null { if ( intention.custom_offer_amount === null || intention.custom_offer_amount === undefined || !intention.custom_offer_currency ) { return null; } const amount = intention.custom_offer_amount; let value: string; switch (intention.custom_offer_currency) { case "pix": value = `R$ ${amount.toFixed(2)}`; break; case "tibia_coins": value = `${Math.round(amount).toLocaleString("pt-BR")} TC`; break; case "gold_coins": value = `${Math.round(amount).toLocaleString("pt-BR")} GP`; break; default: value = amount.toLocaleString("pt-BR"); } return { value, date: intention.custom_offer_created_at ? new Date(intention.custom_offer_created_at).toLocaleString("pt-BR") : null, }; } export function IntentionDetailModal({ open, onOpenChange, intention, listingId, onUpdate, }: IntentionDetailModalProps) { const { user } = useSession(); const queryClient = useQueryClient(); const [sellerResponse, setSellerResponse] = useState(""); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [listing, setListing] = useState<{ seller_id: number; listing_status: string; } | null>(null); const [showMarkSoldDialog, setShowMarkSoldDialog] = useState(false); const [markingSold, setMarkingSold] = useState(false); // Buscar detalhes do listing para verificar se usuário é dono e status useEffect(() => { if (open && listingId) { fetch(`/api/listings/${listingId}`) .then((res) => res.json()) .then((data) => { if (data.success && data.listing) { setListing(data.listing); } }) .catch((err) => console.error("Erro ao buscar listing:", err)); } }, [open, listingId]); const isOwner = user && listing && user.userId === listing.seller_id; const canMarkAsSold = isOwner && listing && (listing.listing_status === "active" || listing.listing_status === "in_escrow"); const canAcceptOrReject = intention.status === "pending"; const customOffer = formatCustomOffer(intention); useEffect(() => { if (open) { setSellerResponse(intention.seller_response ?? ""); } }, [open, intention.seller_response]); const handleAccept = async () => { setLoading(true); setError(null); try { const res = await fetch( `/api/listings/${listingId}/intentions/${intention.intention_id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ status: "accepted", seller_response: sellerResponse || undefined, }), }, ); const data = await res.json(); if (!res.ok || !data.success) { throw new Error(data.error || "Erro ao aceitar intenção"); } if (onUpdate) onUpdate(); onOpenChange(false); } catch (err) { setError(err instanceof Error ? err.message : "Erro ao aceitar intenção"); } finally { setLoading(false); } }; const handleReject = async () => { setLoading(true); setError(null); try { const res = await fetch( `/api/listings/${listingId}/intentions/${intention.intention_id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ status: "rejected", seller_response: sellerResponse || undefined, }), }, ); const data = await res.json(); if (!res.ok || !data.success) { throw new Error(data.error || "Erro ao rejeitar intenção"); } if (onUpdate) onUpdate(); onOpenChange(false); } catch (err) { setError( err instanceof Error ? err.message : "Erro ao rejeitar intenção", ); } finally { setLoading(false); } }; const handleMarkAsSold = async () => { setMarkingSold(true); try { const res = await fetch(`/api/listings/${listingId}/mark-sold`, { method: "POST", }); if (!res.ok) { const data = await res.json(); throw new Error(data.error || "Erro ao marcar como vendido"); } // Invalidar cache para atualizar a lista queryClient.invalidateQueries({ queryKey: ["listings"] }); queryClient.invalidateQueries({ queryKey: ["my-listings"] }); if (onUpdate) onUpdate(); setShowMarkSoldDialog(false); onOpenChange(false); } catch (error) { console.error("Erro ao marcar como vendido:", error); alert( error instanceof Error ? error.message : "Erro ao marcar como vendido", ); } finally { setMarkingSold(false); } }; return ( Intenção de Compra {getStatusBadge(intention.status)} Detalhes da intenção de compra de{" "} {intention.buyer?.username || "usuário"}
{/* Informações do comprador */}
{intention.buyer?.username.charAt(0).toUpperCase() || "?"}
{intention.buyer?.username || "Usuário"}

{intention.buyer?.email || "Email não disponível"}

{/* Informações da intenção */}
{getPaymentMethodLabel(intention.payment_method)}
{new Date(intention.created_at).toLocaleString("pt-BR")}
{customOffer && (
{customOffer.value}
{customOffer.date && (

Enviada em {customOffer.date}

)}
)} {/* Mensagem do comprador */} {intention.buyer_message && (

{intention.buyer_message}

)} {/* Resposta do vendedor */} {intention.seller_response && (

{intention.seller_response}

)}
{/* Campo de resposta (apenas se pendente) */} {canAcceptOrReject && (