import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:on_field_work/helpers/services/api_service.dart'; import 'package:on_field_work/model/document/document_filter_model.dart'; import 'package:on_field_work/model/document/documents_list_model.dart'; import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; class DocumentController extends GetxController { // ==================== Observables ==================== final isLoading = false.obs; final documents = [].obs; final filters = Rxn(); // Selected filters (multi-select) final selectedUploadedBy = [].obs; final selectedCategory = [].obs; final selectedType = [].obs; final selectedTag = [].obs; // Pagination final pageNumber = 1.obs; final pageSize = 20; final hasMore = true.obs; // Error handling final errorMessage = ''.obs; // Preferences final showInactive = false.obs; // Search final searchQuery = ''.obs; final searchController = TextEditingController(); // Additional filters final isUploadedAt = true.obs; final isVerified = RxnBool(); final startDate = Rxn(); final endDate = Rxn(); // ==================== Lifecycle ==================== @override void onClose() { // Don't dispose searchController here - it's managed by the page super.onClose(); } // ==================== API Methods ==================== /// Fetch document filters for entity Future fetchFilters(String entityTypeId) async { try { final response = await ApiService.getDocumentFilters(entityTypeId); if (response != null && response.success) { filters.value = response.data; } else { errorMessage.value = response?.message ?? 'Failed to fetch filters'; _showError('Failed to load filters'); } } catch (e) { errorMessage.value = 'Error fetching filters: $e'; _showError('Error loading filters'); debugPrint('❌ Error fetching filters: $e'); } } /// Toggle document active/inactive state Future toggleDocumentActive( String id, { required bool isActive, required String entityTypeId, required String entityId, }) async { try { isLoading.value = true; final success = await ApiService.deleteDocumentApi( id: id, isActive: isActive, ); if (success) { // Refresh list after state change await fetchDocuments( entityTypeId: entityTypeId, entityId: entityId, reset: true, ); // Show success snackbar showAppSnackbar( title: 'Success', message: isActive ? 'Document deactivated' : 'Document activated', type: SnackbarType.success, ); return true; } else { errorMessage.value = 'Failed to update document state'; _showError('Failed to update document state'); return false; } } catch (e) { errorMessage.value = 'Error updating document: $e'; _showError('Error updating document: $e'); debugPrint('❌ Error toggling document state: $e'); return false; } finally { isLoading.value = false; } } /// Fetch documents for entity with pagination Future fetchDocuments({ required String entityTypeId, required String entityId, String? filter, String? searchString, bool reset = false, }) async { try { if (reset) { pageNumber.value = 1; documents.clear(); hasMore.value = true; } if (!hasMore.value && !reset) return; if (isLoading.value) return; isLoading.value = true; final response = await ApiService.getDocumentListApi( entityTypeId: entityTypeId, entityId: entityId, filter: filter ?? '', searchString: searchString ?? searchQuery.value, pageNumber: pageNumber.value, pageSize: pageSize, isActive: !showInactive.value, ); if (response != null && response.success) { if (response.data?.data.isNotEmpty ?? false) { documents.addAll(response.data!.data); pageNumber.value++; } else { hasMore.value = false; } errorMessage.value = ''; } else { errorMessage.value = response?.message ?? 'Failed to fetch documents'; if (documents.isEmpty) { _showError('Failed to load documents'); } else { showAppSnackbar( title: 'Warning', message: 'No more documents to load', type: SnackbarType.warning, ); } } } catch (e) { errorMessage.value = 'Error fetching documents: $e'; if (documents.isEmpty) { _showError('Error loading documents'); } else { showAppSnackbar( title: 'Error', message: 'Error fetching additional documents', type: SnackbarType.error, ); } debugPrint('❌ Error fetching documents: $e'); } finally { isLoading.value = false; } } // ==================== Helper Methods ==================== /// Clear all selected filters void clearFilters() { selectedUploadedBy.clear(); selectedCategory.clear(); selectedType.clear(); selectedTag.clear(); isUploadedAt.value = true; isVerified.value = null; startDate.value = null; endDate.value = null; } /// Check if any filters are active bool hasActiveFilters() { return selectedUploadedBy.isNotEmpty || selectedCategory.isNotEmpty || selectedType.isNotEmpty || selectedTag.isNotEmpty || startDate.value != null || endDate.value != null || isVerified.value != null; } /// Show error message via snackbar void _showError(String message) { showAppSnackbar( title: 'Error', message: message, type: SnackbarType.error, ); } /// Reset controller state void reset() { documents.clear(); clearFilters(); searchController.clear(); searchQuery.value = ''; pageNumber.value = 1; hasMore.value = true; showInactive.value = false; errorMessage.value = ''; } }