import { ref } from 'vue' import { useToast } from './useToast' import { useApi } from './useApi' import { buildConstructeurRequestPayload, uniqueConstructeurIds } from '~/shared/constructeurUtils' import { useConstructeurs } from './useConstructeurs' const products = ref([]) const total = ref(0) const loading = ref(false) const loaded = ref(false) const error = ref(null) const replaceInCache = (item) => { if (!item?.id) { return false } const index = products.value.findIndex((product) => product.id === item.id) if (index === -1) { products.value.unshift(item) return true } const clone = products.value.slice() clone[index] = item products.value = clone return false } export function useProducts () { const { showError } = useToast() const { get, post, patch, delete: del } = useApi() const { ensureConstructeurs } = useConstructeurs() const withResolvedConstructeurs = async (product) => { if (!product || typeof product !== 'object') { return product } const ids = uniqueConstructeurIds( product.constructeurIds, product.constructeurs, product.constructeur, ) const hasConstructeurs = Array.isArray(product.constructeurs) && product.constructeurs.length > 0 if (ids.length && !hasConstructeurs) { const resolved = await ensureConstructeurs(ids) if (resolved.length) { product.constructeurs = resolved product.constructeurIds = ids } } return product } const loadProducts = async (options = {}) => { if (loading.value) { return { success: true, data: { items: products.value, total: total.value }, } } if (loaded.value && !options.force) { return { success: true, data: { items: products.value, total: total.value }, } } loading.value = true error.value = null try { const result = await get('/products?limit=100') if (result.success) { const items = Array.isArray(result.data?.items) ? result.data.items : [] const enrichedItems = await Promise.all(items.map((item) => withResolvedConstructeurs(item))) products.value = enrichedItems total.value = typeof result.data?.total === 'number' ? result.data.total : items.length loaded.value = true } else if (result.error) { error.value = result.error showError(`Impossible de charger les produits: ${result.error}`) } return result } catch (err) { console.error('Erreur lors du chargement des produits:', err) const message = err?.message ?? 'Erreur inconnue' error.value = message showError(`Impossible de charger les produits: ${message}`) return { success: false, error: message } } finally { loading.value = false } } const createProduct = async (payload) => { const normalizedPayload = buildConstructeurRequestPayload(payload) loading.value = true error.value = null try { const result = await post('/products', normalizedPayload) if (result.success && result.data) { const enriched = await withResolvedConstructeurs(result.data) const added = replaceInCache(enriched) if (added) { total.value += 1 } } else if (result.error) { error.value = result.error showError(result.error) } return result } catch (err) { console.error('Erreur lors de la création du produit:', err) const message = err?.message ?? 'Erreur inconnue' error.value = message showError(message) return { success: false, error: message } } finally { loading.value = false } } const updateProduct = async (id, payload) => { const normalizedPayload = buildConstructeurRequestPayload(payload) loading.value = true error.value = null try { const result = await patch(`/products/${id}`, normalizedPayload) if (result.success && result.data) { const enriched = await withResolvedConstructeurs(result.data) replaceInCache(enriched) } else if (result.error) { error.value = result.error showError(result.error) } return result } catch (err) { console.error('Erreur lors de la mise à jour du produit:', err) const message = err?.message ?? 'Erreur inconnue' error.value = message showError(message) return { success: false, error: message } } finally { loading.value = false } } const deleteProduct = async (id) => { loading.value = true error.value = null try { const result = await del(`/products/${id}`) if (result.success) { const removed = products.value.find((product) => product.id === id) products.value = products.value.filter((product) => product.id !== id) total.value = Math.max(0, total.value - 1) } else if (result.error) { error.value = result.error showError(result.error) } return result } catch (err) { console.error('Erreur lors de la suppression du produit:', err) const message = err?.message ?? 'Erreur inconnue' error.value = message showError(message) return { success: false, error: message } } finally { loading.value = false } } const getProduct = async (id, options = {}) => { const shouldForce = !!options.force if (!shouldForce) { const cached = products.value.find((product) => product.id === id) if (cached && Array.isArray(cached.constructeurs) && cached.constructeurs.length > 0) { return { success: true, data: cached } } } try { const result = await get(`/products/${id}`) if (result.success && result.data) { const enriched = await withResolvedConstructeurs(result.data) replaceInCache(enriched) return { success: true, data: enriched } } return result } catch (err) { console.error('Erreur lors du chargement du produit:', err) const message = err?.message ?? 'Erreur inconnue' return { success: false, error: message } } } const clearProductsCache = () => { products.value = [] total.value = 0 loaded.value = false error.value = null } return { products, total, loading, loaded, error, loadProducts, createProduct, updateProduct, deleteProduct, getProduct, clearProductsCache, } }