'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, getProductEffectivePrice } from '@/lib/pricing-engine'; import { useBrand } from '@/context/BrandContext'; import { getProductSocialProof } from '@/lib/social-proof'; import { renderClientTemplate } from '@/lib/templates-client'; import { OptimizedImage } from '@/components/ui/OptimizedImage'; 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; const displaySizes = Array.from( new Set([...ALL_STANDARD_SIZES, ...(product.sizes || [])]) ).sort((a, b) => parseInt(a, 10) - parseInt(b, 10)); // 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); // Precio dinámico efectivo según colorway y talla seleccionada const currentPrice = getProductEffectivePrice(product, selectedColor, selectedSize); const socialProof = getProductSocialProof(product); const separation = calculateSeparationBreakdown(currentPrice); const handleAdd = () => { if (!isSizeInStock) return; onAddToCart( { ...product, name: `${product.modelName || product.name} (${selectedColor.colorName})`, retailPrice: currentPrice, images: selectedColor.images || [selectedImage], }, selectedSize ); setAdded(true); setTimeout(() => { setAdded(false); onClose(); }, 1200); }; // Pedido normal por WhatsApp const handleWhatsAppDirect = () => { const phone = currentBrand.whatsappNumber || '573167455877'; const rawText = renderClientTemplate('product_direct_inquiry', { tienda_nombre: currentBrand.name, zapatilla_nombre: product.modelName || product.name, color_nombre: selectedColor.colorName, talla: selectedSize, precio: formatCOP(currentPrice), ciudad: selectedCity.name, marca: product.brand || 'Sneakers', }); window.open(`https://wa.me/${phone}?text=${encodeURIComponent(rawText)}`, '_blank'); }; // Solicitud especial de talla no disponible const handleWhatsAppRequestSize = (sizeToRequest: string) => { const phone = currentBrand.whatsappNumber || '573167455877'; const rawText = renderClientTemplate('product_request_size', { tienda_nombre: currentBrand.name, zapatilla_nombre: product.modelName || product.name, color_nombre: selectedColor.colorName, talla: sizeToRequest, ciudad: selectedCity.name, marca: product.brand || 'Sneakers', }); window.open(`https://wa.me/${phone}?text=${encodeURIComponent(rawText)}`, '_blank'); }; return (
{/* Close Button */} {/* Left: Images & Color Preview */}
-{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 || product.images).length} 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(currentPrice)} {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 && (
ESTILO/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; const sizePrice = getProductEffectivePrice(product, selectedColor, size); const hasCustomSizePrice = sizePrice !== product.retailPrice; return ( ); })}
{/* Banner: ¿No encuentras tu talla? */}

¿No encuentras tu talla exacta?

Verificamos disponibilidad con bodega.

{/* 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.
)}
); };