(function() { const BrandCatalog = { currentBrand: null, currentCategory: null, state: 'brands', _lastItems: [], _allBrands: [], _offset: 0, _limit: 50, _total: 0, _getToken: function() { return localStorage.getItem('pos_token'); }, _headers: function() { var token = this._getToken(); return { 'Authorization': 'Bearer ' + (token || ''), 'Content-Type': 'application/json' }; }, _checkAuth: function(resp) { if (resp.status === 401) { localStorage.removeItem('pos_token'); window.location.href = '/pos/login'; return false; } return true; }, el: function(id) { return document.getElementById(id); }, show: function() { if (!this._getToken()) { window.location.href = '/pos/login'; return; } this.el('brandCatalogOverlay').style.display = 'block'; document.body.style.overflow = 'hidden'; this.loadBrands(); }, hide: function() { this.el('brandCatalogOverlay').style.display = 'none'; document.body.style.overflow = ''; this.reset(); }, reset: function() { this.currentBrand = null; this.currentCategory = null; this.state = 'brands'; this._lastItems = []; this._allBrands = []; this._offset = 0; this._total = 0; }, loading: function(on) { this.el('brandCatalogLoading').style.display = on ? 'block' : 'none'; }, setContent: function(html) { this.el('brandCatalogContent').innerHTML = html; }, setBreadcrumb: function(html) { this.el('brandCatalogBreadcrumb').innerHTML = html; }, // ---------- BRANDS ---------- loadBrands: function() { this.loading(true); this.state = 'brands'; this.setBreadcrumb('Marcas de vehiculo'); var self = this; fetch('/pos/api/catalog/vehicle-brands', { headers: this._headers() }) .then(function(r) { if (!self._checkAuth(r)) return null; return r.json(); }) .then(function(data) { if (!data) return; self.loading(false); self._allBrands = data.brands || []; if (!self._allBrands.length) { self.setContent('

No se encontraron marcas.

'); return; } self.renderBrandList(self._allBrands); }) .catch(function(err) { self.loading(false); self.setContent('

Error al cargar marcas: ' + escapeHtml(err.message) + '

'); }); }, renderBrandList: function(brands) { var html = '
' + '' + '
'; brands.forEach(function(b) { html += '
' + '
' + escapeHtml(b.name) + '
' + '
' + (b.part_count || 0) + ' refacciones
' + '
'; }); this.setContent(html); }, filterBrands: function(query) { var q = query.toLowerCase().trim(); if (!q) { this.renderBrandList(this._allBrands); return; } var filtered = this._allBrands.filter(function(b) { return b.name.toLowerCase().indexOf(q) !== -1; }); this.renderBrandList(filtered); }, selectBrand: function(brandName) { this.currentBrand = brandName; this.loadCategories(brandName); }, // ---------- CATEGORIES ---------- loadCategories: function(brandName) { this.loading(true); this.state = 'categories'; this.setBreadcrumb( 'Marcas' + escapeHtml(brandName) + '' ); var self = this; fetch('/pos/api/catalog/brand-categories?brand=' + encodeURIComponent(brandName), { headers: this._headers() }) .then(function(r) { if (!self._checkAuth(r)) return null; return r.json(); }) .then(function(data) { if (!data) return; self.loading(false); if (!data.categories || !data.categories.length) { self.setContent( '
' + '

No se encontraron categorias para ' + escapeHtml(brandName) + '.

' + '' + '
' ); return; } var html = ''; data.categories.forEach(function(c) { html += '
' + '
' + escapeHtml(c.name) + '
' + '
' + c.part_count + ' refacciones
' + '
'; }); self.setContent(html); }) .catch(function(err) { self.loading(false); self.setContent('

Error al cargar categorias: ' + escapeHtml(err.message) + '

'); }); }, selectCategory: function(catId, catName) { this.currentCategory = { id: catId, name: catName }; this._offset = 0; this.loadParts(this.currentBrand, catId, ''); }, // ---------- PARTS ---------- loadParts: function(brandName, categoryId, searchTerm) { this.loading(true); this.state = 'parts'; this.setBreadcrumb( 'Marcas › ' + '' + escapeHtml(brandName) + ' › ' + '' + escapeHtml(this.currentCategory.name) + '' ); var url = '/pos/api/catalog/brand-parts?brand=' + encodeURIComponent(brandName) + '&category_id=' + encodeURIComponent(categoryId) + '&limit=' + this._limit + '&offset=' + this._offset; if (searchTerm) { url += '&search=' + encodeURIComponent(searchTerm); } var self = this; fetch(url, { headers: this._headers() }) .then(function(r) { if (!self._checkAuth(r)) return null; return r.json(); }) .then(function(data) { if (!data) return; self.loading(false); self._lastItems = data.items || []; self._total = data.total || 0; self._offset = data.offset || 0; if (!data.items || !data.items.length) { self.renderPartsList([], searchTerm); return; } self.renderPartsList(data.items, searchTerm); }) .catch(function(err) { self.loading(false); self.setContent('

Error al cargar refacciones: ' + escapeHtml(err.message) + '

'); }); }, renderPartsList: function(items, searchTerm) { var html = '
' + '' + '' + '' + '
'; if (!items.length) { html += '
' + '

No se encontraron refacciones.

' + '' + '
'; this.setContent(html); return; } var startIdx = this._offset + 1; var endIdx = this._offset + items.length; html += '
' + 'Mostrando ' + startIdx + '-' + endIdx + ' de ' + this._total + ' refacciones' + '
'; html += '
'; items.forEach(function(p) { var price = p.local_price ? '$' + Number(p.local_price).toFixed(2) : 'Consultar precio'; var img = '/pos/static/images/placeholder-part.png'; var stockBadge = p.local_stock > 0 ? '' + p.local_stock + ' en stock' : 'Sin stock local'; html += '
' + '
' + '' + '
' + '
' + '
' + escapeHtml(p.oem_part_number || 'N/A') + stockBadge + '
' + '
' + escapeHtml(p.name || '') + '
' + '
' + price + '
' + '' + '
' + '
'; }); html += '
'; var hasPrev = this._offset > 0; var hasNext = (this._offset + this._limit) < this._total; var pageNum = Math.floor(this._offset / this._limit) + 1; var totalPages = Math.ceil(this._total / this._limit) || 1; html += '
' + '' + 'Pagina ' + pageNum + ' de ' + totalPages + '' + '' + '
'; this.setContent(html); }, searchParts: function(term) { this._offset = 0; this.loadParts(this.currentBrand, this.currentCategory.id, term); }, clearPartsSearch: function() { this._offset = 0; this.loadParts(this.currentBrand, this.currentCategory.id, ''); }, goToPage: function(newOffset) { if (newOffset < 0) return; this._offset = newOffset; var searchInput = document.getElementById('partsSearchInput'); var term = searchInput ? searchInput.value : ''; this.loadParts(this.currentBrand, this.currentCategory.id, term); }, addToCart: function(partId, event) { if (event) event.stopPropagation(); var part = this._lastItems.find(function(p) { return p.id === partId; }); if (!part) { alert('Error: no se encontro la refaccion'); return; } if (window.CatalogApp && CatalogApp.addToCart) { CatalogApp.addToCart({ id: part.id, part_number: part.oem_part_number || 'N/A', name: part.name || 'Refaccion', brand: '', price: part.local_price || 0, tax_rate: 0.16, unit: 'PZA', stock: part.local_stock || 0, source: 'oem-brand', inventory_id: null }, 1); var btn = event.target; var oldText = btn.textContent; btn.textContent = 'Agregado!'; btn.style.background = 'var(--color-success)'; setTimeout(function() { btn.textContent = oldText; btn.style.background = ''; }, 1500); return; } alert('Carrito no disponible. Asegurate de que la pagina haya cargado completamente.'); } }; function escapeHtml(text) { if (!text) return ''; var div = document.createElement('div'); div.textContent = text; return div.innerHTML; } window.BrandCatalog = BrandCatalog; })();