import { useEffect, useMemo, useRef, useState } from "react"; import AsyncStorage from "@react-native-async-storage/async-storage"; export type Todo = { id: string; title: string; done: boolean; createdAt: number; }; const STORAGE_KEY = "todos.v1"; const DEBOUNCE_MS = 300; export function useTodos() { const [todos, setTodos] = useState([]); const timer = useRef | null>(null); // load once useEffect(() => { (async () => { const raw = await AsyncStorage.getItem(STORAGE_KEY); if (raw) setTodos(JSON.parse(raw)); })(); }, []); // debounce save useEffect(() => { if (timer.current) clearTimeout(timer.current); timer.current = setTimeout(() => { AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(todos)).catch((e) => { console.warn("Debounce warn: ", e); }); }, DEBOUNCE_MS); return () => { if (timer.current) clearTimeout(timer.current); }; }, [todos]); const activeTodos = useMemo(() => todos.filter((t) => !t.done), [todos]); const doneTodos = useMemo(() => todos.filter((t) => t.done), [todos]); const leftCount = useMemo(() => activeTodos.length, [activeTodos]); const add = (title: string) => { const t = title.trim(); if (!t) return; const id = `${Date.now}-${Math.random().toString(36).slice(2, 8)}`; setTodos([ { id, title: t, done: false, createdAt: Date.now(), }, ...todos, ]); }; const toggle = (id: string) => setTodos( todos.map((it) => it.id === id ? { ...it, done: !it.done, } : it ) ); const remove = (id: string) => setTodos(todos.filter((it) => it.id !== id)); const clearDone = () => setTodos(todos.filter((it) => !it.done)); const completeAll = () => setTodos(todos.map((it) => ({ ...it, done: true }))); return { todos, setTodos, activeTodos, doneTodos, leftCount, add, toggle, remove, clearDone, completeAll, }; }