import { ref } from 'vue' import { useApi } from './useApi' import { useToast } from './useToast' import { extractCollection } from '~/shared/utils/apiHelpers' export interface Constructeur { id: string name: string email?: string | null phone?: string | null } interface ConstructeurResult { success: boolean data?: Constructeur | Constructeur[] error?: string } const constructeurs = ref([]) const loading = ref(false) const loaded = ref(false) const uniqueConstructeurs = (items: Constructeur[] = []): Constructeur[] => { const map = new Map() items.forEach((item) => { if (item && typeof item === 'object' && typeof item.id === 'string') { map.set(item.id, item) } }) return Array.from(map.values()) } const normalizeIds = (ids: unknown[] = []): string[] => { if (!Array.isArray(ids)) { return [] } return Array.from( new Set( ids .map((value) => (typeof value === 'string' ? value.trim() : '')) .filter((value) => value.length > 0), ), ) } const upsertConstructeurs = (items: Constructeur[] = []) => { if (!Array.isArray(items) || !items.length) { return } const merged = uniqueConstructeurs([...constructeurs.value, ...items]) constructeurs.value = merged } const getIndexedConstructeur = (id: string): Constructeur | null => constructeurs.value.find((item) => item && item.id === id) || null const pendingFetches = new Map>() export function useConstructeurs() { const { get, post, patch, delete: del } = useApi() const { showSuccess, showError } = useToast() const loadConstructeurs = async (search = '', options: { force?: boolean } = {}): Promise => { if (!search && !options.force && loaded.value) { return { success: true, data: constructeurs.value } } loading.value = true try { const query = search ? `?search=${encodeURIComponent(search)}` : '' const result = await get(`/constructeurs${query}`) if (result.success) { const items = extractCollection(result.data) constructeurs.value = uniqueConstructeurs(items) if (!search) loaded.value = true } return result as ConstructeurResult } catch (error) { const err = error as Error console.error('Erreur lors du chargement des fournisseurs:', error) return { success: false, error: err.message } } finally { loading.value = false } } const searchConstructeurs = async (search = ''): Promise => { return loadConstructeurs(search) } const createConstructeur = async (data: Partial): Promise => { loading.value = true try { const result = await post('/constructeurs', data) if (result.success) { upsertConstructeurs([result.data as Constructeur]) showSuccess(`Fournisseur "${(result.data as Constructeur).name}" créé`) } else if (result.error) { showError(result.error) } return result as ConstructeurResult } catch (error) { const err = error as Error console.error('Erreur lors de la création du fournisseur:', error) showError('Impossible de créer le fournisseur') return { success: false, error: err.message } } finally { loading.value = false } } const ensureConstructeurs = async (ids: unknown[] = []): Promise => { const normalizedIds = normalizeIds(ids) if (!normalizedIds.length) { return [] } const collected: Constructeur[] = [] const missing: string[] = [] normalizedIds.forEach((id) => { const existing = getIndexedConstructeur(id) if (existing) { collected.push(existing) } else { missing.push(id) } }) if (missing.length) { const fetchTasks = missing.map((id) => { const cached = pendingFetches.get(id) if (cached) { return cached } const task = get(`/constructeurs/${id}`) .then((result) => { if (result.success && result.data) { return result.data as Constructeur } return null }) .catch((error) => { console.error('Erreur lors du chargement du fournisseur:', error) return null }) .finally(() => { pendingFetches.delete(id) }) pendingFetches.set(id, task) return task }) const fetched = await Promise.all(fetchTasks) const validFetched = fetched.filter((item): item is Constructeur => item !== null && item.id !== undefined) if (validFetched.length) { upsertConstructeurs(validFetched) } } return normalizedIds .map((id) => getIndexedConstructeur(id)) .filter((item): item is Constructeur => item !== null) } const updateConstructeur = async (id: string, data: Partial): Promise => { loading.value = true try { const result = await patch(`/constructeurs/${id}`, data) if (result.success) { upsertConstructeurs([result.data as Constructeur]) showSuccess(`Fournisseur "${(result.data as Constructeur).name}" mis à jour`) } else if (result.error) { showError(result.error) } return result as ConstructeurResult } catch (error) { const err = error as Error console.error('Erreur lors de la mise à jour du fournisseur:', error) showError('Impossible de mettre à jour le fournisseur') return { success: false, error: err.message } } finally { loading.value = false } } const deleteConstructeur = async (id: string): Promise => { loading.value = true try { const result = await del(`/constructeurs/${id}`) if (result.success) { constructeurs.value = constructeurs.value.filter((item) => item.id !== id) showSuccess('Fournisseur supprimé') } else if (result.error) { showError(result.error) } return result as ConstructeurResult } catch (error) { const err = error as Error console.error('Erreur lors de la suppression du fournisseur:', error) showError('Impossible de supprimer le fournisseur') return { success: false, error: err.message } } finally { loading.value = false } } const getConstructeurById = (id: string) => getIndexedConstructeur(id) return { constructeurs, loading, loadConstructeurs, searchConstructeurs, createConstructeur, updateConstructeur, deleteConstructeur, getConstructeurById, ensureConstructeurs, } }