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<Payment> _payments = <Payment>[].obs;
  final RxBool _isLoading = false.obs;
  final RxString _error = ''.obs;
  final RxMap<String, dynamic> _paymentSummary = <String, dynamic>{}.obs;
  final RxList<Map<String, dynamic>> _pendingPayments = <Map<String, dynamic>>[].obs;
  
  // Getters
  List<Payment> get payments => _payments.toList();
  bool get isLoading => _isLoading.value;
  String get error => _error.value;
  Map<String, dynamic> get paymentSummary => _paymentSummary;
  List<Map<String, dynamic>> get pendingPayments => _pendingPayments.toList();
  
  @override
  void onInit() {
    super.onInit();
    _error.value = '';
  }
  
  // Record a payment
  Future<bool> 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<void> loadGroupPayments(String groupId, {
    String? status,
    int? month,
    int? year,
    int page = 1,
    int limit = 20,
  }) async {
    try {
      _isLoading.value = true;
      _error.value = '';
      
      final queryParams = <String, dynamic>{
        '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<void> loadMemberPayments(String groupId, String memberId, {
    String? status,
    int page = 1,
    int limit = 20,
  }) async {
    try {
      _isLoading.value = true;
      _error.value = '';
      
      final queryParams = <String, dynamic>{
        '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<bool> 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<void> 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<void> loadPendingPayments(String groupId) async {
    try {
      _isLoading.value = true;
      _error.value = '';
      
      final response = await _apiService.getPendingPayments(groupId);
      
      if (response['success'] == true) {
        _pendingPayments.value = List<Map<String, dynamic>>.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<Payment> getPaymentsByStatus(String status) {
    return _payments.where((payment) => payment.status == status).toList();
  }
  
  List<Payment> 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<String> 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();
    }
  }
}
