import { useState, useCallback, useEffect } from 'react' import type { Task, CreateTaskRequest, ApiError } from '~/types/task' import { TaskStatus } from '~/types/task' import { apiClient } from '~/services/api' interface UseTasksState { tasks: Task[] loading: boolean error: string | null lastFetch: Date | null } interface UseTasksActions { fetchTasks: () => Promise createTask: (data: CreateTaskRequest) => Promise refreshTasks: () => Promise clearError: () => void getTaskById: (id: string) => Task | undefined filterTasksByStatus: (status: TaskStatus) => Task[] } interface UseTasksOptions { autoFetch?: boolean refreshInterval?: number } export function useTasks( options: UseTasksOptions = {} ): UseTasksState & UseTasksActions { const { autoFetch = true, refreshInterval } = options const [state, setState] = useState({ tasks: [], loading: false, error: null, lastFetch: null, }) const clearError = useCallback(() => { setState(prev => ({ ...prev, error: null })) }, []) const fetchTasks = useCallback(async () => { setState(prev => ({ ...prev, loading: true, error: null })) try { const tasks = await apiClient.listTasks() setState(prev => ({ ...prev, tasks, loading: false, lastFetch: new Date(), })) } catch (error) { const apiError = error as ApiError setState(prev => ({ ...prev, loading: false, error: apiError.message, })) } }, []) const createTask = useCallback( async (data: CreateTaskRequest): Promise => { setState(prev => ({ ...prev, loading: true, error: null })) try { const newTask = await apiClient.createTask(data) // Add the new task to the beginning of the list (most recent first) setState(prev => ({ ...prev, tasks: [newTask, ...prev.tasks], loading: false, })) return newTask } catch (error) { const apiError = error as ApiError setState(prev => ({ ...prev, loading: false, error: apiError.message, })) return null } }, [] ) const refreshTasks = useCallback(async () => { // Force refresh without showing loading state if tasks already exist const showLoading = state.tasks.length === 0 if (showLoading) { setState(prev => ({ ...prev, loading: true, error: null })) } else { setState(prev => ({ ...prev, error: null })) } try { const tasks = await apiClient.listTasks() setState(prev => ({ ...prev, tasks, loading: false, lastFetch: new Date(), })) } catch (error) { const apiError = error as ApiError setState(prev => ({ ...prev, loading: false, error: apiError.message, })) } }, [state.tasks]) const getTaskById = useCallback( (id: string): Task | undefined => { return state.tasks.find(task => task.id === id) }, [state.tasks] ) const filterTasksByStatus = useCallback( (status: TaskStatus): Task[] => { return state.tasks.filter(task => task.status === status) }, [state.tasks] ) // Auto-fetch tasks on mount useEffect(() => { if (autoFetch) { fetchTasks() } }, [autoFetch, fetchTasks]) // Set up refresh interval if specified useEffect(() => { if (!refreshInterval) return const interval = setInterval(() => { refreshTasks() }, refreshInterval) return () => clearInterval(interval) }, [refreshInterval, refreshTasks]) return { ...state, fetchTasks, createTask, refreshTasks, clearError, getTaskById, filterTasksByStatus, } }