import 'package:get/get.dart'; import 'package:marco/helpers/services/app_logger.dart'; import 'package:marco/helpers/services/api_service.dart'; import 'package:marco/model/attendance_model.dart'; import 'package:marco/model/project_model.dart'; import 'package:marco/model/employee_model.dart'; import 'package:marco/model/employees/employee_details_model.dart'; import 'package:marco/controller/project_controller.dart'; class EmployeesScreenController extends GetxController { List attendances = []; List projects = []; String? selectedProjectId; List employeeDetails = []; RxBool isAllEmployeeSelected = false.obs; RxList employees = [].obs; RxBool isLoading = false.obs; RxMap uploadingStates = {}.obs; Rxn selectedEmployeeDetails = Rxn(); RxBool isLoadingEmployeeDetails = false.obs; @override void onInit() { super.onInit(); fetchAllProjects(); final projectId = Get.find().selectedProject?.id; if (projectId != null) { selectedProjectId = projectId; fetchEmployeesByProject(projectId); } else if (isAllEmployeeSelected.value) { fetchAllEmployees(); } else { clearEmployees(); } } Future fetchAllProjects() async { isLoading.value = true; await _handleApiCall( ApiService.getProjects, onSuccess: (data) { projects = data.map((json) => ProjectModel.fromJson(json)).toList(); logSafe( "Projects fetched: ${projects.length} projects loaded.", level: LogLevel.info, ); }, onEmpty: () { logSafe("No project data found or API call failed.", level: LogLevel.warning); }, ); isLoading.value = false; update(); } void clearEmployees() { employees.clear(); logSafe("Employees cleared", level: LogLevel.info); update(['employee_screen_controller']); } Future fetchAllEmployees() async { isLoading.value = true; await _handleApiCall( ApiService.getAllEmployees, onSuccess: (data) { employees.assignAll(data.map((json) => EmployeeModel.fromJson(json))); logSafe( "All Employees fetched: ${employees.length} employees loaded.", level: LogLevel.info, ); }, onEmpty: () { employees.clear(); logSafe("No Employee data found or API call failed.", level: LogLevel.warning); }, ); isLoading.value = false; update(['employee_screen_controller']); } Future fetchEmployeesByProject(String? projectId) async { if (projectId == null || projectId.isEmpty) { logSafe("Project ID is required but was null or empty.", level: LogLevel.error); return; } isLoading.value = true; await _handleApiCall( () => ApiService.getAllEmployeesByProject(projectId), onSuccess: (data) { employees.assignAll(data.map((json) => EmployeeModel.fromJson(json))); for (var emp in employees) { uploadingStates[emp.id] = false.obs; } logSafe( "Employees fetched: ${employees.length} for project $projectId", level: LogLevel.info, ); }, onEmpty: () { employees.clear(); logSafe("No employees found for project $projectId.", level: LogLevel.warning, ); }, onError: (e) { logSafe("Error fetching employees for project $projectId", level: LogLevel.error, error: e, ); }, ); isLoading.value = false; update(['employee_screen_controller']); } Future fetchEmployeeDetails(String? employeeId) async { if (employeeId == null || employeeId.isEmpty) return; isLoadingEmployeeDetails.value = true; await _handleSingleApiCall( () => ApiService.getEmployeeDetails(employeeId), onSuccess: (data) { selectedEmployeeDetails.value = EmployeeDetailsModel.fromJson(data); logSafe("Employee details loaded for $employeeId", level: LogLevel.info, ); }, onEmpty: () { selectedEmployeeDetails.value = null; logSafe("No employee details found for $employeeId", level: LogLevel.warning, ); }, onError: (e) { selectedEmployeeDetails.value = null; logSafe("Error fetching employee details for $employeeId", level: LogLevel.error, error: e, ); }, ); isLoadingEmployeeDetails.value = false; } Future _handleApiCall( Future?> Function() apiCall, { required Function(List) onSuccess, required Function() onEmpty, Function(dynamic error)? onError, }) async { try { final response = await apiCall(); if (response != null && response.isNotEmpty) { onSuccess(response); } else { onEmpty(); } } catch (e) { if (onError != null) { onError(e); } else { logSafe("API call error", level: LogLevel.error, error: e); } } } Future _handleSingleApiCall( Future?> Function() apiCall, { required Function(Map) onSuccess, required Function() onEmpty, Function(dynamic error)? onError, }) async { try { final response = await apiCall(); if (response != null && response.isNotEmpty) { onSuccess(response); } else { onEmpty(); } } catch (e) { if (onError != null) { onError(e); } else { logSafe("API call error", level: LogLevel.error, error: e); } } } }