import 'package:wanisclient/models/notification_model.dart'; import 'package:flutter/material.dart'; import '../config/api_response.dart'; import '../config/enum/action_enum.dart'; import '../config/enum/notification_status_enum.dart'; import '../models/dynamic_response.dart'; import '../services/auth_services.dart'; import '../services/notificaitons_services.dart'; class NotificationProvider with ChangeNotifier { final NotificationService _notificationService = NotificationService(); final AuthServices _authService = AuthServices(); List _notifications = []; bool _isLoading = false; bool _isRefreshing = false; bool _hasMore = true; int _currentPage = 0; int _totalPages = 1; List get notifications => _notifications; bool get isLoading => _isLoading; bool get isRefreshing => _isRefreshing; bool get hasMore => _hasMore; /// Fetches notifications with optional filtering by action or status. Future fetchNotifications({ int page = 0, int size = 10, ActionEnum? action, NotificationStatus? status, String? date, }) async { if (page == 0) { _isRefreshing = true; } else { _isLoading = true; } notifyListeners(); APIResponse response; try { if (action != null) { response = await _notificationService.getAllByActionPaginated( action, page, size); } else if (status != null) { response = await _notificationService.getAllByStatusPaginated( status, page, size); } else { response = await _notificationService.getAllPaginated(page, size); } if (response.isValidResponse) { if (page == 0) { _notifications = (response.data as DynamicResponse) .content .map((item) => NotificationModel.fromJson(item)) .toList(); } else { _notifications.addAll((response.data as DynamicResponse) .content .map((item) => NotificationModel.fromJson(item)) .toList()); } _currentPage = (response.data as DynamicResponse).currentPage; _totalPages = (response.data as DynamicResponse).totalPages; _hasMore = _currentPage < _totalPages - 1; } else { if (response.statusCode == 401) { // Attempt to refresh token APIResponse refreshResponse = await _authService.refreshToken(); if (refreshResponse.isValidResponse && refreshResponse.data != null) { // Retry the failed request if (action != null) { response = await _notificationService.getAllByActionPaginated( action, page, size); } else if (status != null) { response = await _notificationService.getAllByStatusPaginated( status, page, size); } else { response = await _notificationService.getAllPaginated(page, size); } if (response.isValidResponse) { if (page == 0) { _notifications = (response.data as DynamicResponse) .content .map((item) => NotificationModel.fromJson(item)) .toList(); } else { _notifications.addAll((response.data as DynamicResponse) .content .map((item) => NotificationModel.fromJson(item)) .toList()); } _currentPage = (response.data as DynamicResponse).currentPage; _totalPages = (response.data as DynamicResponse).totalPages; _hasMore = _currentPage < _totalPages - 1; } else { _hasMore = false; print("Error after token refresh: ${response.errorMessage}"); } } else { // Token refresh failed, prompt user to log in _hasMore = false; print("Token refresh failed: ${refreshResponse.errorMessage}"); // Optionally, navigate to the login screen or show a dialog } } else { _hasMore = false; print("Error: ${response.errorMessage}"); } } } catch (e) { _hasMore = false; print("Exception: $e"); } finally { _isLoading = false; _isRefreshing = false; notifyListeners(); } } /// Loads more notifications for pagination. Future loadMoreNotifications({ ActionEnum? action, NotificationStatus? status, String? date, }) async { if (_hasMore && !_isLoading) { await fetchNotifications( page: _currentPage + 1, size: 10, action: action, status: status, date: date, ); } } /// Refreshes the notifications list. Future refreshNotifications({ ActionEnum? action, NotificationStatus? status, String? date, }) async { await fetchNotifications( page: 0, size: 10, action: action, status: status, date: date, ); } /// Saves a new notification. Future> saveNotification( NotificationModel notification) async { APIResponse response = await _notificationService.saveNotification(notification); if (response.isValidResponse && response.data != null) { _notifications.insert( 0, response.data!); // Add to the beginning of the list notifyListeners(); } return response; } /// Updates an existing notification. Future> updateNotification( int id, NotificationModel notification) async { APIResponse response = await _notificationService.updateNotification(id, notification); if (response.isValidResponse && response.data != null) { int index = _notifications.indexWhere((n) => n.id == id); if (index != -1) { _notifications[index] = response.data!; notifyListeners(); } } return response; } /// Updates the status of a notification. Future> updateNotificationStatus( int id, NotificationStatus status) async { APIResponse response = await _notificationService.updateNotificationStatus(id, status); if (response.isValidResponse && response.data != null) { int index = _notifications.indexWhere((n) => n.id == id); if (index != -1) { _notifications[index] = _notifications[index].copyWith(status: status); notifyListeners(); } } return response; } /// Marks all notifications as read. Future> markAllAsRead() async { APIResponse response = await _notificationService.readAllNotifications(); if (response.isValidResponse) { _notifications = _notifications.map((notification) { return notification.copyWith(status: NotificationStatus.READ); }).toList(); notifyListeners(); } return response; } /// Retrieves the latest notification. Future> getLatestNotification() async { APIResponse response = await _notificationService.getLastNotification(); if (response.isValidResponse && response.data != null) { _notifications.insert( 0, response.data!); // Add to the beginning of the list notifyListeners(); } return response; } /// Deletes a notification by ID. Future> deleteNotification(int id) async { APIResponse response = await _notificationService.deleteNotification(id); if (response.isValidResponse) { _notifications.removeWhere((n) => n.id == id); notifyListeners(); } return response; } }