/* * File: useAIPredictions.ts * Description: Custom hook for AI Predictions functionality * Design & Developed by Tech4Biz Solutions * Copyright (c) Spurrin Innovations. All rights reserved. */ import { useCallback, useEffect, useMemo } from 'react'; import { useAppDispatch, useAppSelector } from '../../../store/hooks'; // Import Redux actions and selectors import { fetchAIPredictions, setSearchQuery, setUrgencyFilter, setSeverityFilter, setCategoryFilter, clearAllFilters, updateCaseReview, } from '../redux'; import { selectPaginatedCases, selectIsLoading, selectError, selectSearchQuery, selectUrgencyFilter, selectSeverityFilter, selectCategoryFilter, selectCasesStatistics, selectActiveFiltersCount, selectCurrentPage, selectTotalPages, } from '../redux'; // Import auth selector import { selectUser } from '../../Auth/redux/authSelectors'; // Import types import type { AIPredictionState } from '../types'; // ============================================================================ // INTERFACES // ============================================================================ interface UseAIPredictionsOptions { autoLoad?: boolean; refreshInterval?: number; } interface UseAIPredictionsReturn { // Data cases: ReturnType; statistics: ReturnType; // Loading states isLoading: boolean; error: string | null; // Filters searchQuery: string; urgencyFilter: AIPredictionState['selectedUrgencyFilter']; severityFilter: AIPredictionState['selectedSeverityFilter']; categoryFilter: AIPredictionState['selectedCategoryFilter']; activeFiltersCount: number; // Pagination currentPage: number; totalPages: number; // Actions loadPredictions: () => Promise; refreshPredictions: () => Promise; setSearch: (query: string) => void; setUrgency: (filter: AIPredictionState['selectedUrgencyFilter']) => void; setSeverity: (filter: AIPredictionState['selectedSeverityFilter']) => void; setCategory: (filter: AIPredictionState['selectedCategoryFilter']) => void; clearFilters: () => void; reviewCase: (caseId: string, reviewData?: Partial<{ review_status: 'pending' | 'reviewed' | 'confirmed' | 'disputed'; reviewed_by: string; review_notes: string; priority: 'critical' | 'high' | 'medium' | 'low'; }>) => Promise; // Computed properties hasFilters: boolean; isEmpty: boolean; hasError: boolean; } // ============================================================================ // USE AI PREDICTIONS HOOK // ============================================================================ /** * useAIPredictions Hook * * Purpose: Custom hook for managing AI predictions state and actions * * Features: * - Automatic data loading on mount * - Search and filtering functionality * - Case review management * - Error handling * - Loading states * - Computed properties for UI state * - Auto-refresh capability * - Type-safe actions and selectors */ export const useAIPredictions = (options: UseAIPredictionsOptions = {}): UseAIPredictionsReturn => { const { autoLoad = true, refreshInterval, } = options; // ============================================================================ // REDUX STATE // ============================================================================ const dispatch = useAppDispatch(); // Auth state const user = useAppSelector(selectUser); // AI Predictions state const cases = useAppSelector(selectPaginatedCases); const statistics = useAppSelector(selectCasesStatistics); const isLoading = useAppSelector(selectIsLoading); const error = useAppSelector(selectError); const searchQuery = useAppSelector(selectSearchQuery); const urgencyFilter = useAppSelector(selectUrgencyFilter); const severityFilter = useAppSelector(selectSeverityFilter); const categoryFilter = useAppSelector(selectCategoryFilter); const activeFiltersCount = useAppSelector(selectActiveFiltersCount); const currentPage = useAppSelector(selectCurrentPage); const totalPages = useAppSelector(selectTotalPages); // ============================================================================ // MEMOIZED VALUES // ============================================================================ /** * Has Filters * * Purpose: Check if any filters are active */ const hasFilters = useMemo(() => activeFiltersCount > 0, [activeFiltersCount]); /** * Is Empty * * Purpose: Check if the cases list is empty */ const isEmpty = useMemo(() => cases.length === 0, [cases.length]); /** * Has Error * * Purpose: Check if there's an error */ const hasError = useMemo(() => error !== null, [error]); // ============================================================================ // ACTIONS // ============================================================================ /** * Load Predictions * * Purpose: Load AI predictions from API */ const loadPredictions = useCallback(async () => { if (!user?.access_token) { throw new Error('User not authenticated'); } try { const params = { page: currentPage, limit: 20, ...(urgencyFilter !== 'all' && { urgency: urgencyFilter }), ...(severityFilter !== 'all' && { severity: severityFilter }), ...(categoryFilter !== 'all' && { category: categoryFilter }), ...(searchQuery.trim() && { search: searchQuery.trim() }), }; await dispatch(fetchAIPredictions({ token: user.access_token, params, })).unwrap(); } catch (error) { console.error('Failed to load AI predictions:', error); throw error; } }, [ dispatch, user?.access_token, currentPage, urgencyFilter, severityFilter, categoryFilter, searchQuery, ]); /** * Refresh Predictions * * Purpose: Refresh AI predictions data */ const refreshPredictions = useCallback(async () => { await loadPredictions(); }, [loadPredictions]); /** * Set Search * * Purpose: Set search query */ const setSearch = useCallback((query: string) => { dispatch(setSearchQuery(query)); }, [dispatch]); /** * Set Urgency Filter * * Purpose: Set urgency filter */ const setUrgency = useCallback((filter: AIPredictionState['selectedUrgencyFilter']) => { dispatch(setUrgencyFilter(filter)); }, [dispatch]); /** * Set Severity Filter * * Purpose: Set severity filter */ const setSeverity = useCallback((filter: AIPredictionState['selectedSeverityFilter']) => { dispatch(setSeverityFilter(filter)); }, [dispatch]); /** * Set Category Filter * * Purpose: Set category filter */ const setCategory = useCallback((filter: AIPredictionState['selectedCategoryFilter']) => { dispatch(setCategoryFilter(filter)); }, [dispatch]); /** * Clear Filters * * Purpose: Clear all active filters */ const clearFilters = useCallback(() => { dispatch(clearAllFilters()); }, [dispatch]); /** * Review Case * * Purpose: Update case review status */ const reviewCase = useCallback(async ( caseId: string, reviewData: Partial<{ review_status: 'pending' | 'reviewed' | 'confirmed' | 'disputed'; reviewed_by: string; review_notes: string; priority: 'critical' | 'high' | 'medium' | 'low'; }> = {} ) => { if (!user?.access_token) { throw new Error('User not authenticated'); } try { const defaultReviewData = { review_status: 'reviewed' as const, reviewed_by: user.display_name || user.email || 'Current User', ...reviewData, }; await dispatch(updateCaseReview({ caseId, reviewData: defaultReviewData, token: user.access_token, })).unwrap(); } catch (error) { console.error('Failed to review case:', error); throw error; } }, [dispatch, user]); // ============================================================================ // EFFECTS // ============================================================================ /** * Auto-load Effect * * Purpose: Automatically load predictions on mount if enabled */ useEffect(() => { if (autoLoad && user?.access_token) { loadPredictions().catch(console.error); } }, [autoLoad, user?.access_token, loadPredictions]); /** * Auto-refresh Effect * * Purpose: Set up auto-refresh interval if specified */ useEffect(() => { if (!refreshInterval || !user?.access_token) return; const interval = setInterval(() => { loadPredictions().catch(console.error); }, refreshInterval); return () => clearInterval(interval); }, [refreshInterval, user?.access_token, loadPredictions]); /** * Filter Change Effect * * Purpose: Reload data when filters change */ useEffect(() => { if (user?.access_token) { loadPredictions().catch(console.error); } }, [urgencyFilter, severityFilter, categoryFilter, searchQuery, currentPage]); // ============================================================================ // RETURN // ============================================================================ return { // Data cases, statistics, // Loading states isLoading, error, // Filters searchQuery, urgencyFilter, severityFilter, categoryFilter, activeFiltersCount, // Pagination currentPage, totalPages, // Actions loadPredictions, refreshPredictions, setSearch, setUrgency, setSeverity, setCategory, clearFilters, reviewCase, // Computed properties hasFilters, isEmpty, hasError, }; }; /* * End of File: useAIPredictions.ts * Design & Developed by Tech4Biz Solutions * Copyright (c) Spurrin Innovations. All rights reserved. */