import { STORAGE_KEYS } from '@/common/constants/storageKeys'; import { buildDefaultSuggestions, normalizeSuggestions } from '@/add-log/suggestions'; import type { Suggestion } from '@/types/foodlog'; import AsyncStorage from '@react-native-async-storage/async-storage'; import * as Crypto from 'expo-crypto'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; export function useLogSuggestions() { const [suggestions, setSuggestions] = useState([]); const mountedRef = useRef(true); const defaultSuggestions = useMemo(() => buildDefaultSuggestions(), []); useEffect(() => { mountedRef.current = true; const raf = requestAnimationFrame(() => { AsyncStorage.getItem(STORAGE_KEYS.SUGGESTIONS).then(data => { if (!mountedRef.current) return; if (data) { try { const parsed = JSON.parse(data); const normalized = normalizeSuggestions(parsed); if (normalized && normalized.length > 0) { setSuggestions(normalized); return; } } catch { /* parse error */ } } setSuggestions(defaultSuggestions); }); }); return () => { mountedRef.current = false; cancelAnimationFrame(raf); }; }, [defaultSuggestions]); const saveSuggestions = useCallback((updated: Suggestion[]) => { setSuggestions(updated); AsyncStorage.setItem(STORAGE_KEYS.SUGGESTIONS, JSON.stringify(updated)); }, []); const addSuggestion = useCallback( (name: string, ingredients: string[]) => { const trimmedName = name.trim(); if (!trimmedName) return; if (suggestions.some(s => s.label.toLowerCase() === trimmedName.toLowerCase())) return; saveSuggestions([ ...suggestions, { id: Crypto.randomUUID(), label: trimmedName, ingredients }, ]); }, [suggestions, saveSuggestions] ); const deleteSuggestion = useCallback( (id: string) => { saveSuggestions(suggestions.filter(s => s.id !== id)); }, [suggestions, saveSuggestions] ); return { suggestions, addSuggestion, deleteSuggestion }; }