import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import '../../core/services/payment_service.dart'; import '../../core/services/chit_group_service.dart'; import '../../core/services/api_service.dart'; import '../../core/models/chit_group.dart'; import '../../core/models/group_member.dart'; import '../../core/utils/snackbar_util.dart'; class AddPastPaymentsDialog extends StatefulWidget { final ChitGroup group; final int monthNumber; const AddPastPaymentsDialog({ super.key, required this.group, required this.monthNumber, }); @override State createState() => _AddPastPaymentsDialogState(); } class _AddPastPaymentsDialogState extends State { final _apiService = ApiService(); final _chitGroupService = Get.find(); Map _memberPaymentStatus = {}; // memberId: paid bool _isLoading = false; int _selectedMonth = 1; int _selectedYear = DateTime.now().year; @override void initState() { super.initState(); _calculateMonthYear(); _initializePaymentStatus(); } void _calculateMonthYear() { if (widget.group.startDate != null) { final startDate = widget.group.startDate!; final targetDate = DateTime( startDate.year, startDate.month + widget.monthNumber - 1, startDate.day, ); _selectedMonth = targetDate.month; _selectedYear = targetDate.year; } } void _initializePaymentStatus() { final members = _chitGroupService.groupMembers; for (var member in members) { _memberPaymentStatus[member.userId] = false; } } Future _handleSubmit() async { final paidMembers = _memberPaymentStatus.entries .where((entry) => entry.value) .map((entry) => entry.key) .toList(); if (paidMembers.isEmpty) { SnackbarUtil.showWarning('Please select at least one member who paid'); return; } setState(() => _isLoading = true); try { int successCount = 0; int errorCount = 0; for (var userId in paidMembers) { final response = await _apiService.recordPayment({ 'group_id': widget.group.id, 'user_id': userId, 'month': _selectedMonth, 'year': _selectedYear, 'amount': widget.group.monthlyInstallment, 'payment_method': 'cash', 'status': 'success', 'paid_at': DateTime.now().toIso8601String(), 'notes': 'Past payment - Month ${widget.monthNumber}', }); if (response['success']) { successCount++; } else { errorCount++; } } if (successCount > 0) { SnackbarUtil.showSuccess( 'Added $successCount payment(s) successfully${errorCount > 0 ? ". $errorCount failed." : ""}', title: 'Payments Added', ); Get.back(result: true); } else { SnackbarUtil.showError('Failed to add payments. Please try again.'); } } catch (e) { SnackbarUtil.showError('Error: ${e.toString()}'); } finally { setState(() => _isLoading = false); } } @override Widget build(BuildContext context) { return Dialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.r)), child: Container( width: 500.w, constraints: BoxConstraints(maxHeight: 600.h), child: Column( mainAxisSize: MainAxisSize.min, children: [ // Header Container( padding: EdgeInsets.all(20.w), decoration: BoxDecoration( gradient: LinearGradient( colors: [Colors.green.shade600, Colors.green.shade700], ), borderRadius: BorderRadius.only( topLeft: Radius.circular(20.r), topRight: Radius.circular(20.r), ), ), child: Row( children: [ Icon(Icons.payment, color: Colors.white, size: 28.w), SizedBox(width: 12.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Add Past Payments', style: TextStyle( fontSize: 20.sp, fontWeight: FontWeight.bold, color: Colors.white, ), ), Text( 'Month ${widget.monthNumber} ($_selectedMonth/$_selectedYear)', style: TextStyle( fontSize: 14.sp, color: Colors.white.withOpacity(0.9), ), ), ], ), ), IconButton( icon: Icon(Icons.close, color: Colors.white, size: 24.w), onPressed: () => Get.back(), ), ], ), ), // Member List Expanded( child: ListView( padding: EdgeInsets.all(24.w), children: [ // Info Container( padding: EdgeInsets.all(12.w), decoration: BoxDecoration( color: Colors.blue.shade50, borderRadius: BorderRadius.circular(12.r), ), child: Row( children: [ Icon(Icons.info_outline, color: Colors.blue.shade700, size: 20.w), SizedBox(width: 12.w), Expanded( child: Text( 'Select members who made their payment for this month', style: TextStyle( fontSize: 14.sp, color: Colors.blue.shade900, ), ), ), ], ), ), SizedBox(height: 20.h), // Members Text( 'Members (₹${_formatCurrency(widget.group.monthlyInstallment)} each)', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, ), ), SizedBox(height: 12.h), Obx(() { final members = _chitGroupService.groupMembers; if (members.isEmpty) { return Container( padding: EdgeInsets.all(24.w), child: Center( child: Text( 'No members in group', style: TextStyle( color: Colors.grey.shade600, fontSize: 14.sp, ), ), ), ); } return Column( children: members.map((member) { final isPaid = _memberPaymentStatus[member.userId] ?? false; return CheckboxListTile( value: isPaid, onChanged: (value) { setState(() { _memberPaymentStatus[member.userId] = value ?? false; }); }, title: Text( member.user?.fullName ?? 'Unknown', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w500, ), ), subtitle: Text( member.user?.mobileNumber ?? '', style: TextStyle(fontSize: 14.sp), ), secondary: CircleAvatar( backgroundColor: isPaid ? Colors.green.shade600 : Colors.grey.shade300, child: Text( member.user?.fullName?.substring(0, 1).toUpperCase() ?? 'M', style: TextStyle(color: Colors.white), ), ), activeColor: Colors.green.shade600, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.r)), tileColor: isPaid ? Colors.green.shade50 : null, ); }).toList(), ); }), SizedBox(height: 16.h), // Summary Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: Colors.grey.shade100, borderRadius: BorderRadius.circular(12.r), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Selected:', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, ), ), Text( '${_memberPaymentStatus.values.where((v) => v).length} members', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.bold, color: Colors.green.shade700, ), ), ], ), ), ], ), ), // Actions Container( padding: EdgeInsets.all(20.w), decoration: BoxDecoration( color: Colors.grey.shade100, borderRadius: BorderRadius.only( bottomLeft: Radius.circular(20.r), bottomRight: Radius.circular(20.r), ), ), child: Row( children: [ Expanded( child: OutlinedButton( onPressed: _isLoading ? null : () => Get.back(), style: OutlinedButton.styleFrom( padding: EdgeInsets.symmetric(vertical: 14.h), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.r), ), ), child: Text( 'Cancel', style: TextStyle(fontSize: 16.sp), ), ), ), SizedBox(width: 16.w), Expanded( flex: 2, child: ElevatedButton( onPressed: _isLoading ? null : _handleSubmit, style: ElevatedButton.styleFrom( backgroundColor: Colors.green.shade600, foregroundColor: Colors.white, padding: EdgeInsets.symmetric(vertical: 14.h), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.r), ), ), child: _isLoading ? SizedBox( height: 20.h, width: 20.w, child: const CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation(Colors.white), ), ) : Text( 'Add Payments', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), ), ), ], ), ), ], ), ), ); } String _formatCurrency(double amount) { final amountStr = amount.toStringAsFixed(0); return amountStr.replaceAllMapped( RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), (Match m) => '${m[1]},', ); } }