import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:test_sa/controllers/api_routes/api_manager.dart'; import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/modules/notification_setting/models/notification_preference_model.dart'; class NotificationSettingProvider extends ChangeNotifier { // State management bool _isLoading = false; bool _isLoadingMore = false; bool _isSaving = false; String? _errorMessage; List _templates = []; // Pagination int _currentPage = 1; final int _pageSize = 10; int _totalRecords = 0; bool _hasMoreData = true; // Getters bool get isLoading => _isLoading; bool get isLoadingMore => _isLoadingMore; bool get isSaving => _isSaving; String? get errorMessage => _errorMessage; List get templates => _templates; bool get hasMoreData => _hasMoreData; bool get isEmpty => _templates.isEmpty && !_isLoading; // Check if there are any modified templates bool get hasChanges => _templates.any((template) => template.isModified); /// Load initial notification preferences Future loadNotificationPreferences({bool refresh = false}) async { if (refresh) { reset(); } if (_isLoading || _isLoadingMore) return; _isLoading = _currentPage == 1; _errorMessage = null; notifyListeners(); try { final body = { 'pageNumber': _currentPage, 'pageSize': _pageSize, }; http.Response response = await ApiManager.instance.post( URLs.getNotificationPreferences, body: body, showToast: false, ); if (response.statusCode >= 200 && response.statusCode < 300) { final jsonData = json.decode(response.body); final notificationResponse = NotificationPreferenceResponse.fromJson(jsonData); if (notificationResponse.isSuccess == true && notificationResponse.data != null) { _totalRecords = notificationResponse.totalRows ?? 0; if (notificationResponse.data!.isNotEmpty) { _templates.addAll(notificationResponse.data!); _currentPage++; _hasMoreData = _templates.length < _totalRecords; } else { _hasMoreData = false; } } else { _errorMessage = notificationResponse.message ?? 'Failed to load notification preferences'; _hasMoreData = false; } } else { _errorMessage = 'Failed to load notification preferences'; _hasMoreData = false; } } catch (error) { _errorMessage = 'An error occurred while loading data'; print('Error in loadNotificationPreferences: $error'); } finally { _isLoading = false; notifyListeners(); } } /// Load more data for pagination Future loadMoreData() async { if (_isLoadingMore || !_hasMoreData || _isLoading) return; _isLoadingMore = true; notifyListeners(); try { final body = { 'pageNumber': _currentPage, 'pageSize': _pageSize, }; http.Response response = await ApiManager.instance.post( URLs.getNotificationPreferences, body: body, showToast: false, ); if (response.statusCode >= 200 && response.statusCode < 300) { final jsonData = json.decode(response.body); final notificationResponse = NotificationPreferenceResponse.fromJson(jsonData); if (notificationResponse.isSuccess == true && notificationResponse.data != null) { if (notificationResponse.data!.isNotEmpty) { _templates.addAll(notificationResponse.data!); _currentPage++; _hasMoreData = _templates.length < _totalRecords; } else { _hasMoreData = false; } } else { _hasMoreData = false; } } else { _hasMoreData = false; } } catch (error) { print('Error in loadMoreData: $error'); } finally { _isLoadingMore = false; notifyListeners(); } } /// Update enable/disable state for a template void updateTemplateState(int index, bool isDisabled) { if (index < 0 || index >= _templates.length) { return; } final template = _templates[index]; // Note: mandatory flag only applies to channel preferences, not to enable/disable toggle // Users can always enable/disable notifications _templates[index] = template.copyWith( isDisabled: isDisabled, isModified: true, ); notifyListeners(); } /// Update selected channels for a template void updateTemplateChannels(int index, List channelIds) { if (index < 0 || index >= _templates.length) return; final template = _templates[index]; _templates[index] = template.copyWith( selectedChannelIds: channelIds, isModified: true, ); _templates[index].selectedChannelIds = channelIds; notifyListeners(); } /// Save all modified preferences Future savePreferences() async { if (!hasChanges) return true; _isSaving = true; _errorMessage = null; notifyListeners(); try { final preferences = _templates.where((t) => t.isModified).map((template) { return { 'notificationTemplateId': template.notificationTemplateId, 'disabled': template.isDisabled ?? false, 'channels': template.selectedChannelIds, }; }).toList(); if (preferences.isEmpty) { _isSaving = false; notifyListeners(); return true; } // Use ApiManager's postList method for array body http.Response response = await ApiManager.instance.postList( URLs.saveNotificationPreferences, body: preferences, showToast: true, ); if (response.statusCode >= 200 && response.statusCode < 300) { // Reset modification flags after successful save for (var i = 0; i < _templates.length; i++) { _templates[i] = _templates[i].copyWith(isModified: false); } _isSaving = false; notifyListeners(); return true; } else { _errorMessage = 'Failed to save preferences'; _isSaving = false; notifyListeners(); return false; } } catch (error) { _errorMessage = 'An error occurred while saving'; _isSaving = false; notifyListeners(); print('Error in savePreferences: $error'); return false; } } /// Reset provider state void reset() { _templates.clear(); _currentPage = 1; _hasMoreData = true; _totalRecords = 0; _isLoading = false; _isLoadingMore = false; _errorMessage = null; } /// Retry loading after error Future retry() async { reset(); await loadNotificationPreferences(); } }