import { Product, City, PaymentMethod, Order, SupplierPost, StoreSettings, Supplier, MonitoredWhatsAppGroup, User } from '@/types'; export const INITIAL_SUPPLIERS: Supplier[] = [ { "id": "sup-jovic", "name": "💎 2️⃣ DIFUSIÓN JOVIC STORE COLOMBIA🍀", "phone": "573167455877", "contactPerson": "Asesor Jovic Store", "address": "Centro / Bodega Cali", "notes": "Proveedor oficial Nike, Jordan, Nocta y Vomero calidades Top.", "isActive": true }, { "id": "sup-ccmio", "name": "EXCLUSIVE CC MÍO 3B", "phone": "573159876543", "contactPerson": "Despachos CC MÍO 3B", "address": "CC MÍO Local 3B, Cali", "notes": "Especialista en Adidas, Coach, Timberland y Skatewear.", "isActive": true }, { "id": "sup-central", "name": "BODEGA CENTRAL MAYORISTA", "phone": "573101234567", "contactPerson": "Logística Despachos", "address": "San Andresito / Cali", "notes": "Despacho rápido en 24 horas para separación inmediata.", "isActive": true } ]; export const INITIAL_CITIES: City[] = [ { id: 'city-cali', name: 'Cali', department: 'Valle del Cauca', shippingCost: 0, deliveryTime: 'Entrega en 24 Horas (Domicilio Local)', allowsContraentrega: true, firstExchangeFree: true, exchangePolicyNote: '1er Cambio de Talla 100% GRATIS en Cali (posteriores con flete estándar)', }, { id: 'city-jamundi', name: 'Jamundí', department: 'Valle del Cauca', shippingCost: 5000, deliveryTime: 'Entrega en 24 Horas', allowsContraentrega: true, firstExchangeFree: true, exchangePolicyNote: '1er Cambio de Talla 100% GRATIS en Jamundí (posteriores con flete estándar)', }, { id: 'city-palmira', name: 'Palmira', department: 'Valle del Cauca', shippingCost: 7000, deliveryTime: 'Entrega en 24 Horas', allowsContraentrega: true, firstExchangeFree: true, exchangePolicyNote: '1er Cambio de Talla 100% GRATIS en Palmira (posteriores con flete estándar)', }, { id: 'city-yumbo', name: 'Yumbo', department: 'Valle del Cauca', shippingCost: 5000, deliveryTime: 'Entrega en 24 Horas', allowsContraentrega: true, firstExchangeFree: true, exchangePolicyNote: '1er Cambio de Talla 100% GRATIS en Yumbo (posteriores con flete estándar)', }, { id: 'city-bogota', name: 'Bogotá D.C.', department: 'Cundinamarca', shippingCost: 12000, deliveryTime: '2 a 3 días hábiles', allowsContraentrega: true, firstExchangeFree: false, exchangePolicyNote: 'Cambio de talla garantizado (flete logístico asumido por el cliente)', }, { id: 'city-medellin', name: 'Medellín', department: 'Antioquia', shippingCost: 12000, deliveryTime: '2 a 3 días hábiles', allowsContraentrega: true, firstExchangeFree: false, exchangePolicyNote: 'Cambio de talla garantizado (flete logístico asumido por el cliente)', }, { id: 'city-barranquilla', name: 'Barranquilla', department: 'Atlántico', shippingCost: 14000, deliveryTime: '3 a 4 días hábiles', allowsContraentrega: true, firstExchangeFree: false, exchangePolicyNote: 'Cambio de talla garantizado (flete logístico asumido por el cliente)', }, { id: 'city-nacional', name: 'Otras Ciudades / Resto del País', department: 'Colombia', shippingCost: 15000, deliveryTime: '2 a 5 días hábiles', allowsContraentrega: false, firstExchangeFree: false, exchangePolicyNote: 'Cambio de talla garantizado (flete nacional asumido por el cliente)', }, ]; // Métodos de Pago configurables por el Admin export const INITIAL_PAYMENT_METHODS: PaymentMethod[] = [ { id: 'pay-bold-link', name: 'Bold.co • PSE, Tarjetas Débito/Crédito, Nequi o QR (Oficial)', type: 'bold', description: 'Paga de forma rápida y 100% segura con tu cuenta Bold. Acepta PSE, Tarjetas Visa/Mastercard y QR de cualquier banco.', requiresDeposit: false, depositAmount: 0, boldPaymentLink: 'https://bold.co/p/carlos-lasso', accountInfo: 'Pasarela Oficial Bold.co • PSE / Tarjetas / QR', isActive: true, }, { id: 'pay-deposit-10k', name: 'Separación con $10.000 + Saldo Contraentrega', type: 'contraentrega', description: 'Asegura tu talla con solo $10.000 COP vía Bold/Nequi/Daviplata y cancelas el saldo restante en efectivo o transferencia cuando el mensajero llegue a tu casa.', requiresDeposit: true, depositAmount: 10000, accountInfo: 'Nequi / Daviplata Oficial: 316 745 5877 (Carlos Andrés Lasso)', boldPaymentLink: 'https://bold.co/p/carlos-lasso', isActive: true, }, { id: 'pay-cod-full', name: 'Pago 100% Contraentrega (Cali y Alrededores)', type: 'contraentrega', description: 'Pagas el 100% del valor total al recibir en tu puerta (válido para entregas urbanas en 24 horas).', requiresDeposit: false, depositAmount: 0, isActive: true, }, { id: 'pay-nequi-full', name: 'Transferencia Total Anticipada Nequi / Daviplata', type: 'nequi', description: 'Paga el 100% anticipado y recibe prioridad de despacho express en 24 horas.', requiresDeposit: false, depositAmount: 0, accountInfo: 'Nequi / Daviplata: 316 745 5877 (Carlos Andrés Lasso)', isActive: true, }, ]; export const INITIAL_PRODUCTS: Product[] = []; export const INITIAL_SUPPLIER_POSTS: SupplierPost[] = [ { id: 'post-1', channelName: 'DIFUSION JOVIC STORE', supplierName: 'DIFUSION JOVIC STORE', supplierPhone: '573134848203', rawMessage: `🔥 DISPONIBLE HOY 🔥\nNike Air Force 1 All White\nTallas: 37 al 43\nMayorista: $90.000 c/u\nDespacho inmediato Cali`, rawImages: [ 'https://images.unsplash.com/photo-1595950653106-6c9ebd614d3a?auto=format&fit=crop&w=800&q=80', ], extractedProduct: { name: 'Nike Air Force 1 Low 07 White Triple', brand: 'Nike', sizes: ['37', '38', '39', '40', '41', '42', '43'], supplierPrice: 90000, suggestedRetailPrice: 125000, category: 'Sneakers / Urbano', confidence: 0.96, supplierName: 'DIFUSION JOVIC STORE', supplierPhone: '573134848203', }, status: 'published_store', receivedAt: 'Hoy, 09:15 AM', }, { id: 'post-2', channelName: 'EXCLUSIVE CC MIO 3B', supplierName: 'EXCLUSIVE CC MIO 3B', supplierPhone: '573159876543', rawMessage: `👟 JORDAN 4 MILITARY BLACK 👟\nFull calidad AAA, caja original\nTallas 38 a 43\nPrecio: $95.000\nDomicilio pago contraentrega`, rawImages: [ 'https://images.unsplash.com/photo-1584735935682-2f2b69dff9d2?auto=format&fit=crop&w=800&q=80', ], extractedProduct: { name: 'Air Jordan 4 Retro Military Black', brand: 'Jordan', sizes: ['38', '39', '40', '41', '42', '43'], supplierPrice: 95000, suggestedRetailPrice: 130000, category: 'Sneakers / Colección', confidence: 0.94, supplierName: 'EXCLUSIVE CC MIO 3B', supplierPhone: '573159876543', }, status: 'published_store', receivedAt: 'Hoy, 10:40 AM', }, ]; export const INITIAL_MONITORED_GROUPS: MonitoredWhatsAppGroup[] = [ { id: 'grp-jovic', jid: '120363049363072784@g.us', name: '💎 2️⃣ DIFUSIÓN JOVIC STORE COLOMBIA🍀', isMonitored: true, supplierId: 'sup-jovic', supplierName: '💎 2️⃣ DIFUSIÓN JOVIC STORE COLOMBIA🍀', profitMarginOverride: 35, autoPublish: true, participantsCount: 450, notes: 'Proveedor oficial Nike, Jordan, Vomero, Nocta y AF1.', }, { id: 'grp-ccmio', jid: '120363024823901923@g.us', name: 'EXCLUSIVE CC MÍO 3B', isMonitored: true, supplierId: 'sup-ccmio', supplierName: 'EXCLUSIVE CC MÍO 3B', profitMarginOverride: 35, autoPublish: true, participantsCount: 380, notes: 'Proveedor oficial Adidas, Coach, Timberland y Skatewear.', }, ]; export const INITIAL_ORDERS: Order[] = [ { id: 'ORD-8921', customerName: 'Mateo Valencia', customerPhone: '3168945120', address: 'Av 6N # 24N-32 Edificio Granada Real', cityId: 'city-cali', cityName: 'Cali (Norte - Granada)', items: [ { productId: 'snk-jordan4-1', productName: 'Nike Air Jordan 4 Retro White Cement', brand: 'Jordan', size: '41', quantity: 1, price: 135000, supplierPrice: 95000, supplierName: '💎 2️⃣ DIFUSIÓN JOVIC STORE COLOMBIA🍀', supplierPhone: '573134848203', image: 'https://images.unsplash.com/photo-1584735935682-2f2b69dff9d2?auto=format&fit=crop&w=800&q=80', }, ], subtotal: 135000, shippingCost: 0, totalAmount: 135000, depositAmount: 10000, balanceDue: 125000, paymentMethodId: 'pay-contraentrega', paymentMethodName: 'Contraentrega Efectivo / Nequi', status: 'pending', createdAt: 'Hoy, 06:45 AM', notes: 'Timbrar en apto 302. Paga con billete de 100 y 50.', }, { id: 'ORD-8922', customerName: 'Valentina Restrepo', customerPhone: '3157829401', address: 'Calle 52N # 4BN-15 Casa 4 La Flora', cityId: 'city-cali', cityName: 'Cali (Norte - La Flora)', items: [ { productId: 'snk-vomero5-1', productName: 'Nike Zoom Vomero 5 Photon Dust Metallic Silver', brand: 'Nike', size: '39', quantity: 1, price: 130000, supplierPrice: 90000, supplierName: '💎 2️⃣ DIFUSIÓN JOVIC STORE COLOMBIA🍀', supplierPhone: '573134848203', image: 'https://images.unsplash.com/photo-1600185365926-3a2ce3cdb9eb?auto=format&fit=crop&w=800&q=80', }, ], subtotal: 130000, shippingCost: 0, totalAmount: 130000, depositAmount: 10000, balanceDue: 120000, paymentMethodId: 'pay-contraentrega', paymentMethodName: 'Contraentrega Nequi', status: 'pending', createdAt: 'Hoy, 07:15 AM', notes: 'Dejar en portería si no contesta.', }, { id: 'ORD-8923', customerName: 'Santiago Henao', customerPhone: '3186523910', address: 'Cra 105 # 14-45 Condominio Portal de la Viga', cityId: 'city-cali', cityName: 'Cali (Sur - Ciudad Jardín)', items: [ { productId: 'snk-campus-1', productName: 'Adidas Campus 00s Core Black White', brand: 'Adidas', size: '40', quantity: 1, price: 125000, supplierPrice: 85000, supplierName: 'EXCLUSIVE CC MÍO 3B', supplierPhone: '573159876543', image: 'https://images.unsplash.com/photo-1525966222134-fcfa99b8ae77?auto=format&fit=crop&w=800&q=80', }, ], subtotal: 125000, shippingCost: 0, totalAmount: 125000, depositAmount: 10000, balanceDue: 115000, paymentMethodId: 'pay-contraentrega', paymentMethodName: 'Contraentrega', status: 'pending', createdAt: 'Hoy, 07:30 AM', notes: 'Recibe en horas de la tarde después de las 2 PM.', }, { id: 'ORD-8924', customerName: 'Camila Ospina', customerPhone: '3114958203', address: 'Cra 85E # 14-80 Apto 501 El Ingenio', cityId: 'city-cali', cityName: 'Cali (Sur - El Ingenio)', items: [ { productId: 'snk-coach-1', productName: 'Coach Low Top Monogram Signature Brown', brand: 'Coach', size: '38', quantity: 1, price: 145000, supplierPrice: 100000, supplierName: 'EXCLUSIVE CC MÍO 3B', supplierPhone: '573159876543', image: 'https://images.unsplash.com/photo-1595950653106-6c9ebd614d3a?auto=format&fit=crop&w=800&q=80', }, ], subtotal: 145000, shippingCost: 0, totalAmount: 145000, depositAmount: 10000, balanceDue: 135000, paymentMethodId: 'pay-contraentrega', paymentMethodName: 'Separación Pagada Bold', status: 'deposit_received', createdAt: 'Hoy, 08:00 AM', notes: 'Cliente ya pagó $10.000 de anticipo.', }, { id: 'ORD-8925', customerName: 'Daniel Caicedo', customerPhone: '3174829105', address: 'Cra 10 # 3-45 San Antonio', cityId: 'city-cali', cityName: 'Cali (Oeste - San Antonio)', items: [ { productId: 'snk-af1-1', productName: 'Nike Air Force 1 07 Low Triple White', brand: 'Nike', size: '42', quantity: 1, price: 120000, supplierPrice: 80000, supplierName: '💎 2️⃣ DIFUSIÓN JOVIC STORE COLOMBIA🍀', supplierPhone: '573134848203', image: 'https://images.unsplash.com/photo-1595950653106-6c9ebd614d3a?auto=format&fit=crop&w=800&q=80', }, ], subtotal: 120000, shippingCost: 0, totalAmount: 120000, depositAmount: 10000, balanceDue: 110000, paymentMethodId: 'pay-contraentrega', paymentMethodName: 'Contraentrega', status: 'pending', createdAt: 'Hoy, 08:20 AM', }, ]; class DataService { private products: Product[] = [...INITIAL_PRODUCTS]; private cities: City[] = [...INITIAL_CITIES]; private paymentMethods: PaymentMethod[] = [...INITIAL_PAYMENT_METHODS]; private suppliers: Supplier[] = [...INITIAL_SUPPLIERS]; private orders: Order[] = [...INITIAL_ORDERS]; private supplierPosts: SupplierPost[] = [...INITIAL_SUPPLIER_POSTS]; getProducts(): Product[] { return this.products; } getProductById(id: string): Product | undefined { return this.products.find((p) => p.id === id); } addProduct(product: Product): Product { this.products.unshift(product); return product; } updateProduct(id: string, updates: Partial): Product | null { const idx = this.products.findIndex((p) => p.id === id); if (idx === -1) return null; this.products[idx] = { ...this.products[idx], ...updates }; return this.products[idx]; } deleteProduct(id: string): boolean { const initialLen = this.products.length; this.products = this.products.filter((p) => p.id !== id); return this.products.length < initialLen; } getSuppliers(includeInactive: boolean = true): Supplier[] { if (includeInactive) return this.suppliers; return this.suppliers.filter((s) => s.isActive !== false); } getSupplierById(id: string): Supplier | undefined { return this.suppliers.find((s) => s.id === id); } addSupplier(supplier: Partial): Supplier { const newSupplier: Supplier = { id: supplier.id || `sup-${Date.now()}`, name: supplier.name || 'Nuevo Proveedor', phone: supplier.phone || '573167455877', contactPerson: supplier.contactPerson || '', address: supplier.address || '', notes: supplier.notes || '', isActive: supplier.isActive !== undefined ? supplier.isActive : true, }; this.suppliers.push(newSupplier); return newSupplier; } updateSupplier(id: string, updates: Partial): Supplier | null { const idx = this.suppliers.findIndex((s) => s.id === id); if (idx === -1) return null; this.suppliers[idx] = { ...this.suppliers[idx], ...updates }; return this.suppliers[idx]; } deleteSupplier(id: string): boolean { // Soft delete (desactivación segura para preservar 100% el historial de pedidos y productos) const supplier = this.suppliers.find((s) => s.id === id); if (!supplier) return false; supplier.isActive = false; return true; } getCities(): City[] { return this.cities; } getCityById(id: string): City | undefined { return this.cities.find((c) => c.id === id); } addCity(city: City): City { this.cities.push(city); return city; } updateCity(id: string, updates: Partial): City | null { const idx = this.cities.findIndex((c) => c.id === id); if (idx === -1) return null; this.cities[idx] = { ...this.cities[idx], ...updates }; return this.cities[idx]; } getPaymentMethods(): PaymentMethod[] { return this.paymentMethods; } updatePaymentMethod(id: string, updates: Partial): PaymentMethod | null { const idx = this.paymentMethods.findIndex((p) => p.id === id); if (idx === -1) return null; this.paymentMethods[idx] = { ...this.paymentMethods[idx], ...updates }; return this.paymentMethods[idx]; } getOrders(): Order[] { return this.orders; } getOrderById(id: string): Order | undefined { return this.orders.find((o) => o.id === id); } addOrder(order: Order): Order { this.orders.unshift(order); return order; } createOrder(orderData: Partial): Order { const newOrder: Order = { id: orderData.id || `ord-${Date.now()}`, customerName: orderData.customerName || 'Cliente', customerPhone: orderData.customerPhone || '', address: orderData.address || '', cityId: orderData.cityId || 'city-cali', cityName: orderData.cityName || 'Cali', items: orderData.items || [], subtotal: orderData.subtotal || 0, shippingCost: orderData.shippingCost || 0, totalAmount: orderData.totalAmount || 0, depositAmount: orderData.depositAmount !== undefined ? orderData.depositAmount : 10000, balanceDue: orderData.balanceDue !== undefined ? orderData.balanceDue : ((orderData.totalAmount || 0) - (orderData.depositAmount !== undefined ? orderData.depositAmount : 10000)), paymentMethodId: orderData.paymentMethodId || 'pay-contraentrega', paymentMethodName: orderData.paymentMethodName || 'Contraentrega', status: orderData.status || 'pending', notes: orderData.notes, createdAt: orderData.createdAt || new Date().toISOString(), }; this.orders.unshift(newOrder); return newOrder; } updateOrder(id: string, updates: Partial): Order | null { const idx = this.orders.findIndex((o) => o.id === id); if (idx === -1) return null; const current = this.orders[idx]; const total = updates.totalAmount !== undefined ? updates.totalAmount : current.totalAmount; const deposit = updates.depositAmount !== undefined ? updates.depositAmount : current.depositAmount; const balanceDue = updates.balanceDue !== undefined ? updates.balanceDue : (total - deposit); this.orders[idx] = { ...current, ...updates, totalAmount: total, depositAmount: deposit, balanceDue, }; return this.orders[idx]; } deleteOrder(id: string): boolean { const initialLen = this.orders.length; this.orders = this.orders.filter((o) => o.id !== id); return this.orders.length < initialLen; } updateOrderStatus(orderId: string, status: Order['status']): Order | null { const order = this.orders.find((o) => o.id === orderId); if (!order) return null; order.status = status; return order; } getSupplierPosts(): SupplierPost[] { return this.supplierPosts; } addSupplierPost(post: SupplierPost): SupplierPost { this.supplierPosts.unshift(post); return post; } saveSupplierPosts(posts: SupplierPost[]): SupplierPost[] { posts.forEach((newP) => { const exists = this.supplierPosts.some( (p) => p.id === newP.id || (p.rawMessage && p.rawMessage === newP.rawMessage && (p as any).channelJid === (newP as any).channelJid) ); if (!exists) { this.supplierPosts.unshift(newP); } }); return this.supplierPosts; } updateSupplierPostStatus(id: string, status: SupplierPost['status']): boolean { const post = this.supplierPosts.find((p) => p.id === id); if (!post) return false; post.status = status; return true; } // Configuración de la Tienda private settings: StoreSettings = { storeName: 'DripZone', slogan: 'Luxury Streetwear & Collectibles', email: 'carlos.andres.lasso@gmail.com', phone: '3167455877', whatsappNumber: '573167455877', instagramHandle: '@dripzone.co', address: 'Bodega Central / Cali', city: 'Cali, Colombia', nequiAccount: '316 745 5877', daviplataAccount: '316 745 5877', accountHolder: 'Carlos Andrés Lasso', boldPaymentLink: 'https://bold.co/p/carlos-lasso', boldApiKey: '', boldMerchantId: '', boldQrUrl: '', boldEnabled: true, defaultProfitMargin: 35, defaultDepositAmount: 10000, }; getSettings(): StoreSettings { return this.settings; } updateSettings(updates: Partial): StoreSettings { this.settings = { ...this.settings, ...updates }; return this.settings; } // Control de Usuarios private users: User[] = [ { id: 'usr-admin-1', name: 'Carlos Andrés Lasso', email: 'carlos.andres.lasso@gmail.com', phone: '3167455877', city: 'Cali', address: 'Centro / Bodega Principal', role: 'admin', isActive: true, createdAt: '2026-01-10', totalOrders: 0, lastLogin: 'Hoy, 08:15 PM', }, { id: 'usr-operator-1', name: 'Andrés Operador Despachos', email: 'despachos@dripzone.co', phone: '3159876543', city: 'Cali', role: 'operator', isActive: true, createdAt: '2026-02-01', totalOrders: 0, lastLogin: 'Hoy, 05:30 PM', }, { id: 'usr-cust-1', name: 'Mateo Gómez (Cliente VIP)', email: 'mateo.sneakers@gmail.com', phone: '3112345678', city: 'Cali', address: 'Calle 5 # 34-12 Apto 402', role: 'customer', isActive: true, createdAt: '2026-02-15', totalOrders: 3, lastLogin: 'Ayer, 08:20 PM', }, ]; getUsers(): User[] { return this.users; } addUser(user: User): User { this.users.unshift(user); return user; } updateUser(id: string, updates: Partial): User | null { const idx = this.users.findIndex((u) => u.id === id); if (idx === -1) return null; this.users[idx] = { ...this.users[idx], ...updates }; return this.users[idx]; } deleteUser(id: string): boolean { const idx = this.users.findIndex((u) => u.id === id); if (idx === -1) return false; this.users.splice(idx, 1); return true; } authenticate(emailOrPhone: string): User | null { const q = emailOrPhone.trim().toLowerCase(); const user = this.users.find( (u) => u.email.toLowerCase() === q || u.phone === q || u.phone.includes(q) ); return user || null; } private monitoredGroups: MonitoredWhatsAppGroup[] = [...INITIAL_MONITORED_GROUPS]; getMonitoredGroups(): MonitoredWhatsAppGroup[] { return this.monitoredGroups; } saveMonitoredGroups(groups: MonitoredWhatsAppGroup[]): MonitoredWhatsAppGroup[] { this.monitoredGroups = groups; return this.monitoredGroups; } toggleGroupMonitoring(idOrJid: string, isMonitored: boolean): MonitoredWhatsAppGroup | null { const grp = this.monitoredGroups.find((g) => g.id === idOrJid || g.jid === idOrJid); if (grp) { grp.isMonitored = isMonitored; return grp; } return null; } } export const dataService = new DataService();