import React, { useState, useEffect } from 'react'; import { X, ArrowLeftRight, ArrowRight, ArrowLeft, Minus, Send, Gift, Loader2, Check } from 'lucide-react'; import { useAuth } from '../contexts/AuthContext'; import { useToast } from '../contexts/ToastContext'; import { getUserCollection, getCardsByIds } from '../services/api'; import { createTrade } from '../services/tradesService'; import { Card } from '../types'; interface CollectionItem { card: Card; quantity: number; } interface TradeCreatorProps { receiverId: string; receiverUsername: string; receiverCollection: CollectionItem[]; onClose: () => void; onTradeCreated: () => void; } interface SelectedCard { card: Card; quantity: number; maxQuantity: number; } type MobileStep = 'want' | 'give' | 'review'; export default function TradeCreator({ receiverId, receiverUsername, receiverCollection, onClose, onTradeCreated, }: TradeCreatorProps) { const { user } = useAuth(); const toast = useToast(); const [myCollection, setMyCollection] = useState([]); const [loading, setLoading] = useState(true); const [submitting, setSubmitting] = useState(false); const [message, setMessage] = useState(''); // Mobile step state const [isGiftMode, setIsGiftMode] = useState(false); const [mobileStep, setMobileStep] = useState('want'); // Cards I'm offering (from my collection) const [myOfferedCards, setMyOfferedCards] = useState>(new Map()); // Cards I want (from their collection) const [wantedCards, setWantedCards] = useState>(new Map()); useEffect(() => { loadMyCollection(); }, [user]); // When gift mode is toggled, adjust mobile step useEffect(() => { if (isGiftMode) { setWantedCards(new Map()); setMobileStep('give'); } else { setMobileStep('want'); } }, [isGiftMode]); const loadMyCollection = async () => { if (!user) return; setLoading(true); try { const collectionMap = await getUserCollection(user.id); if (collectionMap.size === 0) { setMyCollection([]); return; } const cardIds = Array.from(collectionMap.keys()); const cards = await getCardsByIds(cardIds); const collectionWithCards = cards.map((card) => ({ card, quantity: collectionMap.get(card.id) || 0, })); setMyCollection(collectionWithCards); } catch (error) { console.error('Error loading my collection:', error); } finally { setLoading(false); } }; const addToOffer = (card: Card, maxQuantity: number) => { setMyOfferedCards((prev) => { const newMap = new Map(prev); const existing = newMap.get(card.id); if (existing) { if (existing.quantity < existing.maxQuantity) { newMap.set(card.id, { ...existing, quantity: existing.quantity + 1 }); } } else { newMap.set(card.id, { card, quantity: 1, maxQuantity }); } return newMap; }); }; const removeFromOffer = (cardId: string) => { setMyOfferedCards((prev) => { const newMap = new Map(prev); const existing = newMap.get(cardId); if (existing && existing.quantity > 1) { newMap.set(cardId, { ...existing, quantity: existing.quantity - 1 }); } else { newMap.delete(cardId); } return newMap; }); }; const addToWanted = (card: Card, maxQuantity: number) => { setWantedCards((prev) => { const newMap = new Map(prev); const existing = newMap.get(card.id); if (existing) { if (existing.quantity < existing.maxQuantity) { newMap.set(card.id, { ...existing, quantity: existing.quantity + 1 }); } } else { newMap.set(card.id, { card, quantity: 1, maxQuantity }); } return newMap; }); }; const removeFromWanted = (cardId: string) => { setWantedCards((prev) => { const newMap = new Map(prev); const existing = newMap.get(cardId); if (existing && existing.quantity > 1) { newMap.set(cardId, { ...existing, quantity: existing.quantity - 1 }); } else { newMap.delete(cardId); } return newMap; }); }; const handleSubmit = async () => { if (!user) return; if (myOfferedCards.size === 0 && wantedCards.size === 0) { toast.warning('Please select at least one card to trade or gift'); return; } setSubmitting(true); try { const senderCards = Array.from(myOfferedCards.values()).map((item) => ({ cardId: item.card.id, quantity: item.quantity, })); const receiverCards = Array.from(wantedCards.values()).map((item) => ({ cardId: item.card.id, quantity: item.quantity, })); await createTrade({ senderId: user.id, receiverId, message: message || undefined, senderCards, receiverCards, }); onTradeCreated(); } catch (error) { console.error('Error creating trade:', error); toast.error('Failed to create trade'); } finally { setSubmitting(false); } }; const isGift = myOfferedCards.size > 0 && wantedCards.size === 0; const isRequest = myOfferedCards.size === 0 && wantedCards.size > 0; // Mobile navigation const goToNextStep = () => { if (mobileStep === 'want') setMobileStep('give'); else if (mobileStep === 'give') setMobileStep('review'); }; const goToPrevStep = () => { if (mobileStep === 'review') setMobileStep('give'); else if (mobileStep === 'give' && !isGiftMode) setMobileStep('want'); }; const canGoNext = () => { if (mobileStep === 'want') return true; // Can skip wanting cards (request nothing) if (mobileStep === 'give') return true; // Can skip giving cards (gift request) return false; }; const canSubmit = myOfferedCards.size > 0 || wantedCards.size > 0; // Collection grid component const CollectionGrid = ({ items, selectedCards, onAdd, onRemove, emptyMessage, selectionColor, }: { items: CollectionItem[]; selectedCards: Map; onAdd: (card: Card, maxQty: number) => void; onRemove: (cardId: string) => void; emptyMessage: string; selectionColor: 'green' | 'blue'; }) => { if (items.length === 0) { return

{emptyMessage}

; } const ringColor = selectionColor === 'green' ? 'ring-green-500' : 'ring-blue-500'; const badgeColor = selectionColor === 'green' ? 'bg-green-600' : 'bg-blue-500'; return (
{items.map(({ card, quantity }) => { const selected = selectedCards.get(card.id); const remainingQty = quantity - (selected?.quantity || 0); return (
remainingQty > 0 && onAdd(card, quantity)} > {card.name}
{remainingQty}/{quantity}
{selected && ( )}
); })}
); }; // Selected cards summary component const SelectedCardsSummary = ({ cards, onRemove, label, emptyLabel, color, }: { cards: Map; onRemove: (cardId: string) => void; label: string; emptyLabel: string; color: 'green' | 'blue'; }) => { const bgColor = color === 'green' ? 'bg-green-900/50' : 'bg-blue-900/50'; const textColor = color === 'green' ? 'text-green-400' : 'text-blue-400'; return (

{label}:

{cards.size === 0 ? (

{emptyLabel}

) : (
{Array.from(cards.values()).map((item) => (
{item.card.name} x{item.quantity}
))}
)}
); }; // Loading state if (loading) { return (
); } return (
{/* ============ MOBILE VIEW ============ */}
{/* Mobile Header */}

Trade with {receiverUsername}

{/* Gift Toggle */}