import 'package:get/get.dart'; import '../models/payment.dart'; import 'api_service.dart'; class PaymentService extends GetxController { static PaymentService get to => Get.find(); final ApiService _apiService = ApiService(); // Observable state final RxList _payments = [].obs; final RxBool _isLoading = false.obs; final RxString _error = ''.obs; final RxMap _paymentSummary = {}.obs; final RxList> _pendingPayments = >[].obs; // Getters List get payments => _payments.toList(); bool get isLoading => _isLoading.value; String get error => _error.value; Map get paymentSummary => _paymentSummary; List> get pendingPayments => _pendingPayments.toList(); @override void onInit() { super.onInit(); _error.value = ''; } // Record a payment Future recordPayment({ required String groupId, required String userId, required int month, required int year, required double amount, required String paymentMethod, String? transactionId, String? notes, }) async { try { _isLoading.value = true; _error.value = ''; final response = await _apiService.recordPayment({ 'group_id': groupId, 'user_id': userId, 'month': month, 'year': year, 'amount': amount.toStringAsFixed(2), 'payment_method': paymentMethod, 'transaction_id': transactionId, 'notes': notes, }); if (response['success'] == true) { // Add the new payment to the list final payment = Payment.fromJson(response['data']); _payments.add(payment); // Refresh pending payments await loadPendingPayments(groupId); return true; } else { _error.value = response['message'] ?? 'Failed to record payment'; return false; } } catch (e) { print('Record payment error: $e'); _error.value = 'Failed to record payment: $e'; return false; } finally { _isLoading.value = false; } } // Load payments for a group Future loadGroupPayments(String groupId, { String? status, int? month, int? year, int page = 1, int limit = 20, }) async { try { _isLoading.value = true; _error.value = ''; final queryParams = { 'page': page.toString(), 'limit': limit.toString(), }; if (status != null) queryParams['status'] = status; if (month != null) queryParams['month'] = month.toString(); if (year != null) queryParams['year'] = year.toString(); final response = await _apiService.getGroupPayments( groupId, status: status, month: month, year: year, page: page, limit: limit, ); if (response['success'] == true) { final paymentsData = response['data']['payments'] as List; _payments.value = paymentsData.map((json) => Payment.fromJson(json)).toList(); } else { _error.value = response['message'] ?? 'Failed to load payments'; } } catch (e) { print('Load group payments error: $e'); _error.value = 'Failed to load payments: $e'; } finally { _isLoading.value = false; } } // Load payments for a specific member Future loadMemberPayments(String groupId, String memberId, { String? status, int page = 1, int limit = 20, }) async { try { _isLoading.value = true; _error.value = ''; final queryParams = { 'page': page.toString(), 'limit': limit.toString(), }; if (status != null) queryParams['status'] = status; final response = await _apiService.getMemberPayments( groupId, memberId, status: status, page: page, limit: limit, ); if (response['success'] == true) { final paymentsData = response['data']['payments'] as List; _payments.value = paymentsData.map((json) => Payment.fromJson(json)).toList(); } else { _error.value = response['message'] ?? 'Failed to load member payments'; } } catch (e) { print('Load member payments error: $e'); _error.value = 'Failed to load member payments: $e'; } finally { _isLoading.value = false; } } // Update payment status Future updatePaymentStatus(String paymentId, String status, {String? notes}) async { try { _isLoading.value = true; _error.value = ''; final response = await _apiService.updatePaymentStatus(paymentId, status, notes: notes); if (response['success'] == true) { // Update the payment in the list final updatedPayment = Payment.fromJson(response['data']); final index = _payments.indexWhere((p) => p.id == paymentId); if (index != -1) { _payments[index] = updatedPayment; } return true; } else { _error.value = response['message'] ?? 'Failed to update payment status'; return false; } } catch (e) { print('Update payment status error: $e'); _error.value = 'Failed to update payment status: $e'; return false; } finally { _isLoading.value = false; } } // Load payment summary for a group Future loadPaymentSummary(String groupId) async { try { _isLoading.value = true; _error.value = ''; final response = await _apiService.getGroupPaymentSummary(groupId); if (response['success'] == true) { _paymentSummary.value = response['data']; } else { _error.value = response['message'] ?? 'Failed to load payment summary'; } } catch (e) { print('Load payment summary error: $e'); _error.value = 'Failed to load payment summary: $e'; } finally { _isLoading.value = false; } } // Load pending payments for a group Future loadPendingPayments(String groupId) async { try { _isLoading.value = true; _error.value = ''; final response = await _apiService.getPendingPayments(groupId); if (response['success'] == true) { _pendingPayments.value = List>.from(response['data']['pending_payments']); } else { _error.value = response['message'] ?? 'Failed to load pending payments'; } } catch (e) { print('Load pending payments error: $e'); _error.value = 'Failed to load pending payments: $e'; } finally { _isLoading.value = false; } } // Clear error void clearError() { _error.value = ''; } // Clear payments void clearPayments() { _payments.clear(); } // Helper methods List getPaymentsByStatus(String status) { return _payments.where((payment) => payment.status == status).toList(); } List getPaymentsByMonth(int month, int year) { return _payments.where((payment) => payment.month == month && payment.year == year).toList(); } double getTotalAmountByStatus(String status) { return _payments .where((payment) => payment.status == status) .fold(0.0, (sum, payment) => sum + payment.amount); } // Get payment methods for dropdown List get paymentMethods => ['upi', 'bank_transfer', 'cash', 'cheque']; String getPaymentMethodLabel(String method) { switch (method) { case 'upi': return 'UPI'; case 'bank_transfer': return 'Bank Transfer'; case 'cash': return 'Cash'; case 'cheque': return 'Cheque'; default: return method.toUpperCase(); } } }