import 'package:get/get.dart'; import 'package:marco/helpers/services/api_service.dart'; import 'package:marco/helpers/services/app_logger.dart'; import 'package:marco/model/expense/expense_detail_model.dart'; import 'package:marco/model/employee_model.dart'; class ExpenseDetailController extends GetxController { final Rx expense = Rx(null); final RxBool isLoading = false.obs; final RxString errorMessage = ''.obs; final Rx selectedReimbursedBy = Rx(null); final RxList allEmployees = [].obs; bool _isInitialized = false; late String _expenseId; /// Call this once from the screen (NOT inside build) to initialize void init(String expenseId) { if (_isInitialized) return; _isInitialized = true; _expenseId = expenseId; fetchExpenseDetails(); fetchAllEmployees(); } /// Fetch expense details by stored ID Future fetchExpenseDetails() async { isLoading.value = true; errorMessage.value = ''; try { logSafe("Fetching expense details for ID: $_expenseId"); final result = await ApiService.getExpenseDetailsApi(expenseId: _expenseId); if (result != null) { try { expense.value = ExpenseDetailModel.fromJson(result); logSafe("Expense details loaded successfully: ${expense.value?.id}"); } catch (e) { errorMessage.value = 'Failed to parse expense details: $e'; logSafe("Parse error in fetchExpenseDetails: $e", level: LogLevel.error); } } else { errorMessage.value = 'Failed to fetch expense details from server.'; logSafe("fetchExpenseDetails failed: null response", level: LogLevel.error); } } catch (e, stack) { errorMessage.value = 'An unexpected error occurred.'; logSafe("Exception in fetchExpenseDetails: $e", level: LogLevel.error); logSafe("StackTrace: $stack", level: LogLevel.debug); } finally { isLoading.value = false; } } // In ExpenseDetailController List parsePermissionIds(dynamic permissionData) { if (permissionData == null) return []; if (permissionData is List) { // If it's already a List, return a list of Strings. return permissionData .map((e) => e.toString().trim()) .where((e) => e.isNotEmpty) .toList(); } if (permissionData is String) { final clean = permissionData.replaceAll(RegExp(r'[\[\]]'), ''); return clean .split(',') .map((e) => e.trim()) .where((e) => e.isNotEmpty) .toList(); } return []; } /// Fetch all employees Future fetchAllEmployees() async { isLoading.value = true; errorMessage.value = ''; try { final response = await ApiService.getAllEmployees(); if (response != null && response.isNotEmpty) { allEmployees.assignAll(response.map((e) => EmployeeModel.fromJson(e))); logSafe("All Employees fetched: ${allEmployees.length}", level: LogLevel.info); } else { allEmployees.clear(); logSafe("No employees found.", level: LogLevel.warning); } } catch (e) { allEmployees.clear(); logSafe("Error fetching employees", level: LogLevel.error, error: e); } finally { isLoading.value = false; update(); } } /// Update expense with reimbursement info and status Future updateExpenseStatusWithReimbursement({ required String comment, required String reimburseTransactionId, required String reimburseDate, required String reimburseById, required String statusId, }) async { isLoading.value = true; errorMessage.value = ''; try { logSafe("Submitting reimbursement for expense: $_expenseId"); final success = await ApiService.updateExpenseStatusApi( expenseId: _expenseId, statusId: statusId, comment: comment, reimburseTransactionId: reimburseTransactionId, reimburseDate: reimburseDate, reimbursedById: reimburseById, ); if (success) { logSafe("Reimbursement submitted successfully."); await fetchExpenseDetails(); return true; } else { errorMessage.value = "Failed to submit reimbursement."; return false; } } catch (e, stack) { errorMessage.value = 'An unexpected error occurred.'; logSafe("Exception in updateExpenseStatusWithReimbursement: $e", level: LogLevel.error); logSafe("StackTrace: $stack", level: LogLevel.debug); return false; } finally { isLoading.value = false; } } /// Update status for this specific expense Future updateExpenseStatus(String statusId) async { isLoading.value = true; errorMessage.value = ''; try { logSafe("Updating status for expense: $_expenseId -> $statusId"); final success = await ApiService.updateExpenseStatusApi( expenseId: _expenseId, statusId: statusId, ); if (success) { logSafe("Expense status updated successfully."); await fetchExpenseDetails(); return true; } else { errorMessage.value = "Failed to update expense status."; return false; } } catch (e, stack) { errorMessage.value = 'An unexpected error occurred.'; logSafe("Exception in updateExpenseStatus: $e", level: LogLevel.error); logSafe("StackTrace: $stack", level: LogLevel.debug); return false; } finally { isLoading.value = false; } } }