import { defineStore } from "pinia"; import ProductService from "@/services/product"; export const useProductStore = defineStore("product", { state: () => ({ products: [], currentProduct: null, loading: false, isLoading: false, error: null, meta: { current_page: 1, last_page: 1, per_page: 15, total: 0, from: 1, to: 0, }, }), getters: { lowStockProducts: (state) => state.products.filter((product) => product.is_low_stock), expiringProducts: (state) => state.products.filter((product) => product.date_expiration && new Date(product.date_expiration) <= new Date(Date.now() + 30 * 24 * 60 * 60 * 1000) ), categories: (state) => { const categorySet = new Set(state.products.map(product => product.categorie).filter(Boolean)); return Array.from(categorySet).sort(); }, totalProducts: (state) => state.meta.total, totalValue: (state) => state.products.reduce((total, product) => total + (product.stock_actuel * product.prix_unitaire), 0 ), }, actions: { async fetchProducts(params = {}) { this.loading = true; this.error = null; try { const response = await ProductService.getAllProducts(params); this.products = response.data; this.meta = { current_page: response.pagination.current_page, last_page: response.pagination.last_page, per_page: response.pagination.per_page, total: response.pagination.total, from: response.pagination.from, to: response.pagination.to, }; return response; } catch (error: any) { this.error = error?.message || "Erreur lors du chargement des produits"; throw error; } finally { this.loading = false; } }, async createProduct(productData: any) { this.isLoading = true; this.error = null; try { const response = await ProductService.createProduct(productData); const product = response.data; // Add the new product to the beginning of the list this.products.unshift(product); this.meta.total += 1; return product; } catch (error: any) { this.error = error?.message || "Erreur lors de la création du produit"; throw error; } finally { this.isLoading = false; } }, async updateProduct(id: number, productData: any) { this.isLoading = true; this.error = null; try { const response = await ProductService.updateProduct(id, productData); const updatedProduct = response.data; // Update the product in the list const index = this.products.findIndex((p) => p.id === id); if (index !== -1) { this.products[index] = updatedProduct; } // Update current product if it matches if (this.currentProduct?.id === id) { this.currentProduct = updatedProduct; } return updatedProduct; } catch (error: any) { this.error = error?.message || "Erreur lors de la mise à jour du produit"; throw error; } finally { this.isLoading = false; } }, async deleteProduct(id: number) { this.isLoading = true; this.error = null; try { await ProductService.deleteProduct(id); // Remove the product from the list this.products = this.products.filter((p) => p.id !== id); this.meta.total -= 1; // Clear current product if it was deleted if (this.currentProduct?.id === id) { this.currentProduct = null; } return true; } catch (error: any) { this.error = error?.message || "Erreur lors de la suppression du produit"; throw error; } finally { this.isLoading = false; } }, async fetchProduct(id: number) { this.loading = true; this.error = null; try { const response = await ProductService.getProduct(id); this.currentProduct = response.data; return response.data; } catch (error: any) { this.error = error?.message || "Erreur lors du chargement du produit"; throw error; } finally { this.loading = false; } }, async searchProducts(searchTerm: string, exact = false) { this.loading = true; this.error = null; try { const response = await ProductService.searchProducts(searchTerm, exact); // Update current products list with search results this.products = response.data; return response.data; } catch (error: any) { this.error = error?.message || "Erreur lors de la recherche"; throw error; } finally { this.loading = false; } }, async fetchLowStockProducts() { this.loading = true; this.error = null; try { const response = await ProductService.getLowStockProducts(); return response; } catch (error: any) { this.error = error?.message || "Erreur lors du chargement des produits à stock faible"; throw error; } finally { this.loading = false; } }, async fetchProductsByCategory(category: string) { this.loading = true; this.error = null; try { const response = await ProductService.getProductsByCategory(category); return response; } catch (error: any) { this.error = error?.message || "Erreur lors du chargement des produits par catégorie"; throw error; } finally { this.loading = false; } }, async getProductStatistics() { try { const response = await ProductService.getProductStatistics(); return response.data; } catch (error: any) { this.error = error?.message || "Erreur lors du chargement des statistiques"; throw error; } }, async updateStock(productId: number, newStock: number) { try { const response = await ProductService.updateStock(productId, newStock); // Update the product in the list const index = this.products.findIndex((p) => p.id === productId); if (index !== -1) { this.products[index] = response.data; } return response.data; } catch (error: any) { this.error = error?.message || "Erreur lors de la mise à jour du stock"; throw error; } }, resetState() { this.products = []; this.currentProduct = null; this.error = null; this.loading = false; this.isLoading = false; }, // Local filtering functions filterByCategory(category: string) { if (!category) return this.products; return this.products.filter((product: any) => product.categorie === category); }, filterByLowStock() { return this.products.filter((product: any) => product.is_low_stock); }, filterByExpiration(days = 30) { const cutoffDate = new Date(Date.now() + days * 24 * 60 * 60 * 1000); return this.products.filter((product: any) => product.date_expiration && new Date(product.date_expiration) <= cutoffDate ); }, }, });