'use client'; import React, { useState, useEffect } from 'react'; import { X, Star, Truck, ShieldCheck, Zap, MessageCircle, ShoppingBag, Check, Palette, AlertCircle, HelpCircle, Sparkles, ArrowRight, } from 'lucide-react'; import { Product, City, ProductColorVariant } from '@/types'; import { formatCOP, calculateSeparationBreakdown } from '@/lib/pricing-engine'; import { useBrand } from '@/context/BrandContext'; import { getProductSocialProof } from '@/lib/social-proof'; interface ProductModalProps { product: Product | null; onClose: () => void; onAddToCart: (product: Product, size: string) => void; selectedCity: City; } const ALL_STANDARD_SIZES = ['36', '37', '38', '39', '40', '41', '42', '43', '44']; export const ProductModal: React.FC = ({ product, onClose, onAddToCart, selectedCity, }) => { const { currentBrand } = useBrand(); if (!product) return null; // Active colorway variant const colorsList: ProductColorVariant[] = product.colors && product.colors.length > 0 ? product.colors : [ { id: 'col-default', colorName: product.colorName || 'Color Principal', image: product.images[0], images: product.images, sizes: product.sizes, inStock: product.inStock, }, ]; const [selectedColor, setSelectedColor] = useState(colorsList[0]); const [selectedImage, setSelectedImage] = useState(colorsList[0]?.image || product.images[0]); const [availableSizes, setAvailableSizes] = useState(colorsList[0]?.sizes || product.sizes); const [selectedSize, setSelectedSize] = useState( (colorsList[0]?.sizes && colorsList[0].sizes[0]) || product.sizes[0] || '39' ); const [added, setAdded] = useState(false); // When color variant changes, update images & available sizes const handleColorChange = (variant: ProductColorVariant) => { setSelectedColor(variant); setSelectedImage(variant.image || (variant.images && variant.images[0]) || product.images[0]); const nextSizes = variant.sizes && variant.sizes.length > 0 ? variant.sizes : product.sizes; setAvailableSizes(nextSizes); if (!nextSizes.includes(selectedSize)) { setSelectedSize(nextSizes[0] || selectedSize); } }; const isSizeInStock = availableSizes.includes(selectedSize); const socialProof = getProductSocialProof(product); const separation = calculateSeparationBreakdown(product.retailPrice); const handleAdd = () => { if (!isSizeInStock) return; onAddToCart( { ...product, name: `${product.modelName || product.name} (${selectedColor.colorName})`, images: selectedColor.images || [selectedImage], }, selectedSize ); setAdded(true); setTimeout(() => { setAdded(false); onClose(); }, 1200); }; // Pedido normal por WhatsApp const handleWhatsAppDirect = () => { const phone = currentBrand.whatsappNumber || '573167455877'; const text = `Hola ${currentBrand.name}! 👋 Quiero pedir las zapatillas: 👟 *${product.modelName || product.name}* 🎨 Color: *${selectedColor.colorName}* 📏 Talla: *${selectedSize}* (Horma Nacional) 💎 Precio: *${formatCOP(product.retailPrice)} COP* 🚚 Entrega en: *${selectedCity.name}* (Pago Contraentrega) ⚡ Deseo separar con $10.000 COP y cancelar el saldo en mi casa. ¿Me confirman disponibilidad para despacho por favor?`; window.open(`https://wa.me/${phone}?text=${encodeURIComponent(text)}`, '_blank'); }; // Solicitud especial de talla no disponible const handleWhatsAppRequestSize = (sizeToRequest: string) => { const phone = currentBrand.whatsappNumber || '573167455877'; const text = `Hola ${currentBrand.name}! 👋 Estaba revisando la tienda y me gustaron mucho estas zapatillas: 👟 *${product.modelName || product.name}* 🎨 Color: *${selectedColor.colorName}* 📏 Talla que necesito: *${sizeToRequest}* (Actualmente no aparece disponible en stock inmediato) 📍 Ciudad de entrega: *${selectedCity.name}* ¿Es posible conseguir esta talla bajo pedido con sus bodegas aliadas para despacho contraentrega? Quedo muy atento, ¡muchas gracias!`; window.open(`https://wa.me/${phone}?text=${encodeURIComponent(text)}`, '_blank'); }; // All sizes to show (combination of standard sizes and any custom product sizes) const displaySizes = Array.from(new Set([...ALL_STANDARD_SIZES, ...product.sizes])).sort( (a, b) => parseInt(a, 10) - parseInt(b, 10) ); return (
{/* Close Button */} {/* Left: Images & Color Preview */}
{product.name} -{Math.round(((product.originalPrice || 170000) - product.retailPrice) / (product.originalPrice || 170000) * 100)}% OFF {/* Active Color Tag on Image */}
{selectedColor.colorName}
{/* Gallery / Colorway Thumbnails */}
Fotos del Colorway: {selectedColor.images?.length || 1} vistas
{(selectedColor.images && selectedColor.images.length > 0 ? selectedColor.images : product.images).map((img, i) => ( ))}
{/* Trust note */}
{selectedCity.firstExchangeFree ? ( <>1er Cambio de Talla GRATIS en {selectedCity.name} • Cambios posteriores con flete estándar. ) : ( <>Garantía de Cambio en {selectedCity.name} • Envío asegurado contraentrega. )}
{/* Right: Product Details, Colorways, Sizes & WhatsApp Request */}
{/* Header */}
{product.brand} • {product.category || 'Sneakers'} Ref: {product.id.slice(0, 10)}

{product.modelName || product.name}

{socialProof.rating} ({socialProof.reviewsCount} opiniones)
• +{socialProof.salesCount} pares despachados
{/* Price Box */}
{formatCOP(product.retailPrice)} {product.originalPrice && ( {formatCOP(product.originalPrice)} )}
{/* Separation breakdown banner */}

¡Pago Contraentrega en {selectedCity.name}!

Separas con solo {formatCOP(separation.depositAmount)} y pagas los {formatCOP(separation.balanceDue)} al mensajero cuando llegue a tu casa.

{/* Colorways Selector (Si hay más de 1 color o variante) */} {colorsList.length > 0 && (
Color Seleccionado: {selectedColor.colorName}
{colorsList.map((variant) => { const isCurrent = selectedColor.id === variant.id; return ( ); })}
)} {/* Size Selector with Stock & WhatsApp sourcing option */}
Selecciona tu Talla (CO / Nacional): {isSizeInStock ? ( Stock Inmediato ) : ( Solicitud Bajo Pedido )}
{displaySizes.map((size) => { const inStock = availableSizes.includes(size); const isSelected = selectedSize === size; return ( ); })}
{/* Banner: ¿No encuentras tu talla? */}

¿No encuentras tu talla exacta?

Verificamos disponibilidad con bodega en 5 minutos.

{/* Description */}

{product.description}

{/* Shipping note */}
{selectedCity.name}: {selectedCity.deliveryTime} ({selectedCity.shippingCost === 0 ? 'Envío Gratis' : formatCOP(selectedCity.shippingCost)})
{/* Action Buttons */}
{isSizeInStock ? ( <> ) : (
La talla {selectedSize} en {selectedColor.colorName} no tiene despacho inmediato en 24h, pero podemos pedirla a la bodega central para ti.
)}
); };