import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import '../../core/services/chit_group_service.dart'; import '../../core/utils/snackbar_util.dart'; import 'package:intl/intl.dart'; class ImportExistingGroupDialog extends StatefulWidget { const ImportExistingGroupDialog({super.key}); @override State createState() => _ImportExistingGroupDialogState(); } class _ImportExistingGroupDialogState extends State { final _formKey = GlobalKey(); final _nameController = TextEditingController(); final _totalValueController = TextEditingController(); final _monthlyInstallmentController = TextEditingController(); final _durationMonthsController = TextEditingController(); final _maxMembersController = TextEditingController(); final _foremanCommissionController = TextEditingController(); final _drawDateController = TextEditingController(); final _currentMonthController = TextEditingController(); DateTime? _selectedStartDate; bool _isLoading = false; int _step = 1; // Multi-step wizard @override void initState() { super.initState(); _drawDateController.text = '15'; _foremanCommissionController.text = '250'; _currentMonthController.text = '1'; // Default to 6 months ago _selectedStartDate = DateTime.now().subtract(const Duration(days: 180)); } @override void dispose() { _nameController.dispose(); _totalValueController.dispose(); _monthlyInstallmentController.dispose(); _durationMonthsController.dispose(); _maxMembersController.dispose(); _foremanCommissionController.dispose(); _drawDateController.dispose(); _currentMonthController.dispose(); super.dispose(); } Future _selectStartDate() async { final DateTime? picked = await showDatePicker( context: context, initialDate: _selectedStartDate ?? DateTime.now().subtract(const Duration(days: 180)), firstDate: DateTime(2020), lastDate: DateTime.now(), helpText: 'Select when the group started', ); if (picked != null) { setState(() { _selectedStartDate = picked; _calculateCurrentMonth(); }); } } void _calculateCurrentMonth() { if (_selectedStartDate != null) { final now = DateTime.now(); final diff = now.difference(_selectedStartDate!); final monthsPassed = (diff.inDays / 30).floor() + 1; _currentMonthController.text = monthsPassed.toString(); } } void _calculateMonthlyInstallment() { final totalValue = double.tryParse(_totalValueController.text); final durationMonths = int.tryParse(_durationMonthsController.text); final commission = double.tryParse(_foremanCommissionController.text) ?? 250.0; if (totalValue != null && durationMonths != null) { final subscriptionPerMonth = totalValue / durationMonths; final monthlyInstallment = subscriptionPerMonth + commission; _monthlyInstallmentController.text = monthlyInstallment.toStringAsFixed(0); } } Future _handleImport() async { if (_formKey.currentState!.validate()) { if (_selectedStartDate == null) { SnackbarUtil.showError('Please select a start date'); return; } setState(() => _isLoading = true); try { final data = { 'name': _nameController.text.trim(), 'total_value': double.parse(_totalValueController.text), 'monthly_installment': double.parse(_monthlyInstallmentController.text), 'duration_months': int.parse(_durationMonthsController.text), 'max_members': int.parse(_maxMembersController.text), 'foreman_commission_amount': double.parse(_foremanCommissionController.text), 'foreman_commission_type': 'fixed', 'draw_date': int.parse(_drawDateController.text), 'start_date': _selectedStartDate!.toIso8601String(), 'current_month': int.parse(_currentMonthController.text), 'is_import': true, // Flag to indicate this is an existing group 'status': 'active', // Start as active directly }; final success = await ChitGroupService.to.createChitGroup(data); if (success) { SnackbarUtil.showSuccess( 'Existing group imported successfully! You can now add members and past draw results.', title: 'Import Successful', ); Get.back(result: true); } else { SnackbarUtil.showError('Failed to import group. 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: 600.w, constraints: BoxConstraints(maxHeight: 700.h), child: Column( mainAxisSize: MainAxisSize.min, children: [ // Header Container( padding: EdgeInsets.all(20.w), decoration: BoxDecoration( gradient: LinearGradient( colors: [Colors.blue.shade600, Colors.blue.shade700], ), borderRadius: BorderRadius.only( topLeft: Radius.circular(20.r), topRight: Radius.circular(20.r), ), ), child: Row( children: [ Icon(Icons.upload, color: Colors.white, size: 28.w), SizedBox(width: 12.w), Expanded( child: Text( 'Import Existing Chit Group', style: TextStyle( fontSize: 20.sp, fontWeight: FontWeight.bold, color: Colors.white, ), ), ), IconButton( icon: Icon(Icons.close, color: Colors.white, size: 24.w), onPressed: () => Get.back(), ), ], ), ), // Form Expanded( child: SingleChildScrollView( padding: EdgeInsets.all(24.w), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Info Box Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: Colors.blue.shade50, borderRadius: BorderRadius.circular(12.r), border: Border.all(color: Colors.blue.shade200), ), child: Row( children: [ Icon(Icons.info_outline, color: Colors.blue.shade700, size: 20.w), SizedBox(width: 12.w), Expanded( child: Text( 'Import a chit group that has already started. You can add past draw results and payments later.', style: TextStyle( fontSize: 14.sp, color: Colors.blue.shade900, ), ), ), ], ), ), SizedBox(height: 24.h), // Group Name Text( 'Group Name', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), SizedBox(height: 8.h), TextFormField( controller: _nameController, decoration: InputDecoration( hintText: 'e.g., January 2024 Batch', border: OutlineInputBorder(borderRadius: BorderRadius.circular(12.r)), filled: true, fillColor: Colors.grey.shade50, ), validator: (value) => value?.isEmpty ?? true ? 'Required' : null, ), SizedBox(height: 20.h), // Start Date Text( 'When Did This Group Start?', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), SizedBox(height: 8.h), InkWell( onTap: _selectStartDate, child: Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( border: Border.all(color: Colors.grey.shade300), borderRadius: BorderRadius.circular(12.r), color: Colors.grey.shade50, ), child: Row( children: [ Icon(Icons.calendar_today, color: Colors.blue.shade600), SizedBox(width: 12.w), Text( _selectedStartDate != null ? DateFormat('dd/MM/yyyy').format(_selectedStartDate!) : 'Select start date', style: TextStyle(fontSize: 16.sp), ), ], ), ), ), SizedBox(height: 20.h), // Current Month Text( 'Current Month Number', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), SizedBox(height: 8.h), TextFormField( controller: _currentMonthController, keyboardType: TextInputType.number, decoration: InputDecoration( hintText: 'e.g., 6 (if 6 months have passed)', border: OutlineInputBorder(borderRadius: BorderRadius.circular(12.r)), filled: true, fillColor: Colors.grey.shade50, suffixText: 'months elapsed', ), validator: (value) { if (value?.isEmpty ?? true) return 'Required'; final month = int.tryParse(value!); if (month == null || month < 1) return 'Must be at least 1'; return null; }, ), SizedBox(height: 20.h), // Financial Details Header Divider(), SizedBox(height: 12.h), Text( 'Chitfund Details', style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.bold, color: Colors.grey.shade800, ), ), SizedBox(height: 16.h), // Total Value Text('Total Value', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600)), SizedBox(height: 8.h), TextFormField( controller: _totalValueController, keyboardType: TextInputType.number, decoration: InputDecoration( hintText: 'e.g., 100000', prefixText: '₹ ', border: OutlineInputBorder(borderRadius: BorderRadius.circular(12.r)), filled: true, fillColor: Colors.grey.shade50, ), onChanged: (_) => _calculateMonthlyInstallment(), validator: (value) { if (value?.isEmpty ?? true) return 'Required'; if (double.tryParse(value!) == null) return 'Invalid number'; return null; }, ), SizedBox(height: 16.h), // Duration Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Duration (Months)', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600)), SizedBox(height: 8.h), TextFormField( controller: _durationMonthsController, keyboardType: TextInputType.number, decoration: InputDecoration( hintText: 'e.g., 20', border: OutlineInputBorder(borderRadius: BorderRadius.circular(12.r)), filled: true, fillColor: Colors.grey.shade50, ), onChanged: (_) => _calculateMonthlyInstallment(), validator: (value) { if (value?.isEmpty ?? true) return 'Required'; if (int.tryParse(value!) == null) return 'Invalid'; return null; }, ), ], ), ), SizedBox(width: 12.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Max Members', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600)), SizedBox(height: 8.h), TextFormField( controller: _maxMembersController, keyboardType: TextInputType.number, decoration: InputDecoration( hintText: 'e.g., 20', border: OutlineInputBorder(borderRadius: BorderRadius.circular(12.r)), filled: true, fillColor: Colors.grey.shade50, ), validator: (value) { if (value?.isEmpty ?? true) return 'Required'; if (int.tryParse(value!) == null) return 'Invalid'; return null; }, ), ], ), ), ], ), SizedBox(height: 16.h), // Monthly Installment & Commission Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Monthly Installment', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600)), SizedBox(height: 8.h), TextFormField( controller: _monthlyInstallmentController, keyboardType: TextInputType.number, decoration: InputDecoration( hintText: 'e.g., 5250', prefixText: '₹ ', border: OutlineInputBorder(borderRadius: BorderRadius.circular(12.r)), filled: true, fillColor: Colors.grey.shade50, ), validator: (value) { if (value?.isEmpty ?? true) return 'Required'; if (double.tryParse(value!) == null) return 'Invalid'; return null; }, ), ], ), ), SizedBox(width: 12.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Commission', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600)), SizedBox(height: 8.h), TextFormField( controller: _foremanCommissionController, keyboardType: TextInputType.number, decoration: InputDecoration( hintText: 'e.g., 250', prefixText: '₹ ', border: OutlineInputBorder(borderRadius: BorderRadius.circular(12.r)), filled: true, fillColor: Colors.grey.shade50, ), onChanged: (_) => _calculateMonthlyInstallment(), validator: (value) { if (value?.isEmpty ?? true) return 'Required'; if (double.tryParse(value!) == null) return 'Invalid'; return null; }, ), ], ), ), ], ), SizedBox(height: 16.h), // Draw Date Text('Draw Date (Day of Month)', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600)), SizedBox(height: 8.h), TextFormField( controller: _drawDateController, keyboardType: TextInputType.number, decoration: InputDecoration( hintText: 'e.g., 15 (15th of every month)', border: OutlineInputBorder(borderRadius: BorderRadius.circular(12.r)), filled: true, fillColor: Colors.grey.shade50, ), validator: (value) { if (value?.isEmpty ?? true) return 'Required'; final date = int.tryParse(value!); if (date == null || date < 1 || date > 31) return '1-31 only'; return null; }, ), SizedBox(height: 24.h), // Summary Box Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: Colors.green.shade50, borderRadius: BorderRadius.circular(12.r), border: Border.all(color: Colors.green.shade200), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(Icons.info_outline, color: Colors.green.shade700, size: 20.w), SizedBox(width: 8.w), Text( 'Next Steps After Import', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.bold, color: Colors.green.shade800, ), ), ], ), SizedBox(height: 12.h), _buildNextStep('1', 'Add all members to the group'), _buildNextStep('2', 'Record past draw results (if any)'), _buildNextStep('3', 'Record past payments for each member'), _buildNextStep('4', 'Continue with regular monthly operations'), ], ), ), ], ), ), ), ), // 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: 16.h), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.r), ), ), child: Text( 'Cancel', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), ), ), SizedBox(width: 16.w), Expanded( flex: 2, child: ElevatedButton( onPressed: _isLoading ? null : _handleImport, style: ElevatedButton.styleFrom( backgroundColor: Colors.blue.shade600, foregroundColor: Colors.white, padding: EdgeInsets.symmetric(vertical: 16.h), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.r), ), elevation: 2, ), child: _isLoading ? SizedBox( height: 20.h, width: 20.w, child: const CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation(Colors.white), ), ) : Text( 'Import Group', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), ), ), ], ), ), ], ), ), ); } Widget _buildNextStep(String number, String text) { return Padding( padding: EdgeInsets.only(bottom: 8.h), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: 24.w, height: 24.w, decoration: BoxDecoration( color: Colors.green.shade600, shape: BoxShape.circle, ), child: Center( child: Text( number, style: TextStyle( color: Colors.white, fontSize: 12.sp, fontWeight: FontWeight.bold, ), ), ), ), SizedBox(width: 12.w), Expanded( child: Padding( padding: EdgeInsets.only(top: 2.h), child: Text( text, style: TextStyle( fontSize: 14.sp, color: Colors.green.shade900, ), ), ), ), ], ), ); } }