import { WHATSAPP_PHONE } from './config.js'; export function fmtPrice(product) { if (product.europe_price_text) return product.europe_price_text; const n = Number(product.europe_price_number); if (Number.isFinite(n)) { return new Intl.NumberFormat('ca-ES', { style: 'currency', currency: 'EUR' }).format(n); } return '-'; } export function normalizeText(v) { return String(v ?? '').toLowerCase().trim(); } export function parseDescription(description) { const raw = String(description ?? '').trim(); if (!raw) return []; return raw .split(/\n|\r|\||•|;/g) .map(s => s.trim()) .filter(Boolean); } export function getStockState(stock) { const n = Number(stock || 0); if (n <= 1) { return { cls: 'stock-last', label: '🔥 Última unitat' }; } if (n <= 3) { return { cls: 'stock-low', label: `⚠️ Queden poques unitats · ${n} disponibles` }; } return { cls: 'stock-ok', label: `Stock disponible · ${n} unitats` }; } export function getSalesHook(product) { if (product.top_vendes) { return null; } const stock = Number(product.stock || 0); if (stock <= 1) { return { badge: 'Última oportunitat', text: 'Aquest model està a punt d’esgotar-se.' }; } if (stock <= 3) { return { badge: 'Alta demanda', text: 'Model amb poques unitats disponibles.' }; } return { badge: 'Selecció premium', text: 'Una aposta segura per estil i rendiment.' }; } export function buildWhatsappLink(product) { const text = [ 'Hola Blood Bros Sports,', 'voldria encomanar aquest model:', `${product.product_code || ''}`, product.model ? `Model: ${product.model}` : '', product.category ? `Família: ${product.category}` : '', product.colors ? `Colors: ${product.colors}` : '', Number(product.europe_price_number) ? `Preu: ${fmtPrice(product)}` : '', `Stock visible: ${product.stock ?? ''}` ] .filter(Boolean) .join('\n'); if (WHATSAPP_PHONE) { return `https://wa.me/${encodeURIComponent(WHATSAPP_PHONE)}?text=${encodeURIComponent(text)}`; } return `https://api.whatsapp.com/send?text=${encodeURIComponent(text)}`; } export function getFilteredProducts(products, filters) { const q = normalizeText(filters.search); const top = filters.top; const sort = filters.sort; const price = filters.price; let data = products.filter(p => Number(p.stock) >= 1); if (q) { data = data.filter(p => { const hay = [p.product_code, p.model, p.category, p.colors, p.description] .map(normalizeText) .join(' '); return hay.includes(q); }); } if (top === 'top') data = data.filter(p => !!p.top_vendes); if (top === 'normal') data = data.filter(p => !p.top_vendes); if (price !== 'all') { data = data.filter(p => { const n = Number(p.europe_price_number); if (!Number.isFinite(n)) return false; if (price === '0-60') return n <= 60; if (price === '60-80') return n > 60 && n <= 80; if (price === '80+') return n > 80; return true; }); } data.sort((a, b) => { const codeA = String(a.product_code || ''); const codeB = String(b.product_code || ''); const priceA = Number.isFinite(Number(a.europe_price_number)) ? Number(a.europe_price_number) : -Infinity; const priceB = Number.isFinite(Number(b.europe_price_number)) ? Number(b.europe_price_number) : -Infinity; const stockA = Number(a.stock || 0); const stockB = Number(b.stock || 0); switch (sort) { case 'code-desc': return codeB.localeCompare(codeA, 'ca'); case 'price-asc': return priceA - priceB; case 'price-desc': return priceB - priceA; case 'stock-desc': return stockB - stockA; default: return codeA.localeCompare(codeB, 'ca'); } }); return data; }