import { useState, useCallback, useEffect } from "react"; import { listTasks, getTask, createTask, updateTask, deleteTask, VersionConflictError, type TaskSummary, type TaskWithSubtasks, type CreateTaskRequest, type UpdateTaskRequest, } from "../lib/api"; export interface ConflictState { hasConflict: boolean; expectedVersion: number; actualVersion: number; } export function useTasks() { const [tasks, setTasks] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [conflict, setConflict] = useState(null); const fetchTasks = useCallback(async () => { setLoading(true); setError(null); try { const response = await listTasks(); setTasks(response.tasks); } catch (e) { setError(e instanceof Error ? e.message : "Failed to fetch tasks"); } finally { setLoading(false); } }, []); const fetchTask = useCallback( async (id: string): Promise => { setError(null); try { return await getTask(id); } catch (e) { setError(e instanceof Error ? e.message : "Failed to fetch task"); return null; } }, [] ); const saveTask = useCallback( async (data: CreateTaskRequest): Promise => { setError(null); try { const task = await createTask(data); await fetchTasks(); // Refresh list // Return as TaskWithSubtasks return { ...task, subtasks: [] }; } catch (e) { setError(e instanceof Error ? e.message : "Failed to save task"); return null; } }, [fetchTasks] ); const editTask = useCallback( async (id: string, data: UpdateTaskRequest): Promise => { setError(null); setConflict(null); try { await updateTask(id, data); await fetchTasks(); // Refresh list // Re-fetch to get subtasks return await getTask(id); } catch (e) { if (e instanceof VersionConflictError) { setConflict({ hasConflict: true, expectedVersion: e.expectedVersion, actualVersion: e.actualVersion, }); return null; } setError(e instanceof Error ? e.message : "Failed to update task"); return null; } }, [fetchTasks] ); const clearConflict = useCallback(() => { setConflict(null); }, []); const removeTask = useCallback( async (id: string): Promise => { setError(null); try { await deleteTask(id); await fetchTasks(); // Refresh list return true; } catch (e) { setError(e instanceof Error ? e.message : "Failed to delete task"); return false; } }, [fetchTasks] ); // Initial fetch useEffect(() => { fetchTasks(); }, [fetchTasks]); return { tasks, loading, error, conflict, clearConflict, fetchTasks, fetchTask, saveTask, editTask, removeTask, }; }