import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'dart:math' as math; import '../../core/services/chit_group_service.dart'; import '../../core/models/chit_group.dart'; import '../../shared/widgets/draw_animation_selector.dart'; import '../../shared/widgets/recording_overlay.dart'; import '../../core/services/screen_recording_service.dart'; class CombinedDrawDialog extends StatefulWidget { final ChitGroup group; const CombinedDrawDialog({ super.key, required this.group, }); @override State createState() => _CombinedDrawDialogState(); } class _CombinedDrawDialogState extends State with TickerProviderStateMixin { final _formKey = GlobalKey(); final _monthController = TextEditingController(); final _yearController = TextEditingController(); late AnimationController _fadeController; late AnimationController _slideController; late Animation _fadeAnimation; late Animation _slideAnimation; final ScreenRecordingService _recordingService = Get.find(); bool _isLoading = false; bool _isDrawStarted = false; bool _isDrawComplete = false; Map? _winnerData; String? _serverSeed; int? _nonce; List> _eligibleMembers = []; @override void initState() { super.initState(); _initializeForm(); _loadEligibleMembers(); _initializeAnimations(); } @override void dispose() { _monthController.dispose(); _yearController.dispose(); _fadeController.dispose(); _slideController.dispose(); super.dispose(); } void _initializeForm() { final now = DateTime.now(); _monthController.text = now.month.toString(); _yearController.text = now.year.toString(); } void _initializeAnimations() { _fadeController = AnimationController( duration: const Duration(milliseconds: 500), vsync: this, ); _slideController = AnimationController( duration: const Duration(milliseconds: 500), vsync: this, ); _fadeAnimation = Tween( begin: 0.0, end: 1.0, ).animate(CurvedAnimation( parent: _fadeController, curve: Curves.easeInOut, )); _slideAnimation = Tween( begin: const Offset(0, 0.3), end: Offset.zero, ).animate(CurvedAnimation( parent: _slideController, curve: Curves.easeOutCubic, )); _fadeController.forward(); _slideController.forward(); } void _loadEligibleMembers() async { // Load real members from the API final chitGroupService = Get.find(); // Load group members if not already loaded await chitGroupService.loadGroupMembers(widget.group.id); // Get active members who haven't won yet final allMembers = chitGroupService.groupMembers; final pastDraws = chitGroupService.monthlyDraws; final wonMemberIds = pastDraws.map((d) => d.winnerId).toList(); final eligible = allMembers.where((member) { return member.status.toLowerCase() == 'active' && !wonMemberIds.contains(member.userId); }).toList(); setState(() { _eligibleMembers = eligible.map((member) => { 'id': member.userId, 'name': member.user?.fullName ?? 'Unknown', 'mobile': member.user?.mobileNumber ?? '', }).toList(); }); // Show message if no eligible members if (_eligibleMembers.isEmpty) { Get.snackbar( 'No Eligible Members', 'All active members have already won, or no members exist in this group.', backgroundColor: Colors.orange.shade100, colorText: Colors.orange.shade900, ); } } void _startDraw() { if (!_formKey.currentState!.validate()) return; setState(() { _isDrawStarted = true; _generateSeeds(); }); } void _generateSeeds() { // Generate server seed final random = math.Random(); _serverSeed = List.generate(32, (index) => random.nextInt(256)) .map((byte) => byte.toRadixString(16).padLeft(2, '0')) .join(); // Generate nonce _nonce = random.nextInt(1000000); } void _onDrawComplete(String winnerId, Map winnerData) { setState(() { _isDrawComplete = true; _winnerData = winnerData; }); // Stop recording _stopRecordingWithDetails(); } void _startRecording() { _recordingService.startRecording(); } void _stopRecording() { _recordingService.stopRecording(); } void _stopRecordingWithDetails() { final month = int.parse(_monthController.text); final year = int.parse(_yearController.text); _recordingService.saveRecordingWithDetails( groupName: widget.group.name, month: month.toString(), year: year.toString(), serverSeed: _serverSeed ?? '', clientSeed: '', nonce: _nonce ?? 0, winnerName: _winnerData?['name'] ?? 'Unknown', ); } @override Widget build(BuildContext context) { return RecordingOverlay( showRecordingIndicator: true, child: Dialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16.r)), child: Container( width: 500.w, constraints: BoxConstraints(maxHeight: 0.8.sh), child: Column( mainAxisSize: MainAxisSize.min, children: [ // Header Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: Colors.purple.shade600, borderRadius: BorderRadius.only( topLeft: Radius.circular(16.r), topRight: Radius.circular(16.r), ), ), child: Row( children: [ Icon( Icons.casino, color: Colors.white, size: 24.w, ), SizedBox(width: 12.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Monthly Draw', style: TextStyle( color: Colors.white, fontSize: 18.sp, fontWeight: FontWeight.bold, ), ), Text( '${_monthController.text}/${_yearController.text}', style: TextStyle( color: Colors.white.withOpacity(0.9), fontSize: 12.sp, ), ), ], ), ), IconButton( onPressed: () => Navigator.of(context).pop(), icon: const Icon(Icons.close, color: Colors.white), padding: EdgeInsets.zero, constraints: const BoxConstraints(), ), ], ), ), // Content Flexible( child: SingleChildScrollView( padding: EdgeInsets.all(16.w), child: FadeTransition( opacity: _fadeAnimation, child: SlideTransition( position: _slideAnimation, child: Column( children: [ if (!_isDrawStarted) _buildDrawForm(), if (_isDrawStarted && !_isDrawComplete) _buildDrawInProgress(), if (_isDrawComplete) _buildDrawResult(), ], ), ), ), ), ), // Action Buttons Container( padding: EdgeInsets.all(16.w), child: Row( children: [ Expanded( child: OutlinedButton( onPressed: () => Navigator.of(context).pop(), style: OutlinedButton.styleFrom( padding: EdgeInsets.symmetric(vertical: 12.h), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.r), ), ), child: Text( 'Close', style: TextStyle(fontSize: 14.sp), ), ), ), SizedBox(width: 12.w), if (!_isDrawStarted) Expanded( child: ElevatedButton( onPressed: _isLoading ? null : _startDraw, style: ElevatedButton.styleFrom( backgroundColor: Colors.purple.shade600, foregroundColor: Colors.white, padding: EdgeInsets.symmetric(vertical: 12.h), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.r), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.play_arrow, size: 18.w), SizedBox(width: 6.w), Text( 'Start Draw', style: TextStyle(fontSize: 14.sp), ), ], ), ), ), if (_isDrawComplete) Expanded( child: ElevatedButton( onPressed: _saveDrawResult, style: ElevatedButton.styleFrom( backgroundColor: Colors.green.shade600, foregroundColor: Colors.white, padding: EdgeInsets.symmetric(vertical: 12.h), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.r), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.save, size: 18.w), SizedBox(width: 6.w), Text( 'Save Result', style: TextStyle(fontSize: 14.sp), ), ], ), ), ), ], ), ), ], ), ), ), ); } Widget _buildDrawForm() { return Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Draw Details Text( 'Draw Details', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: Colors.grey.shade800, ), ), SizedBox(height: 16.h), Row( children: [ Expanded( child: TextFormField( controller: _monthController, decoration: InputDecoration( labelText: 'Month *', hintText: 'e.g., 12', prefixIcon: const Icon(Icons.calendar_month), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8.r), ), ), keyboardType: TextInputType.number, validator: (value) { if (value == null || value.isEmpty) { return 'Month is required'; } final month = int.tryParse(value); if (month == null || month < 1 || month > 12) { return 'Please enter a valid month (1-12)'; } return null; }, ), ), SizedBox(width: 16.w), Expanded( child: TextFormField( controller: _yearController, decoration: InputDecoration( labelText: 'Year *', hintText: 'e.g., 2024', prefixIcon: const Icon(Icons.calendar_today), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8.r), ), ), keyboardType: TextInputType.number, validator: (value) { if (value == null || value.isEmpty) { return 'Year is required'; } final year = int.tryParse(value); if (year == null || year < 2020 || year > 2030) { return 'Please enter a valid year'; } return null; }, ), ), ], ), SizedBox(height: 16.h), // Quick Info Container( padding: EdgeInsets.all(12.w), decoration: BoxDecoration( color: Colors.grey.shade50, borderRadius: BorderRadius.circular(8.r), border: Border.all(color: Colors.grey.shade200), ), child: Row( children: [ Icon(Icons.info_outline, color: Colors.grey.shade600, size: 16.w), SizedBox(width: 8.w), Expanded( child: Text( 'Draw will use provably fair system with animated selection', style: TextStyle( fontSize: 12.sp, color: Colors.grey.shade700, ), ), ), ], ), ), SizedBox(height: 16.h), // Eligible Members Text( 'Eligible Members (${_eligibleMembers.length})', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: Colors.grey.shade800, ), ), SizedBox(height: 12.h), Container( height: 150.h, decoration: BoxDecoration( border: Border.all(color: Colors.grey.shade300), borderRadius: BorderRadius.circular(8.r), ), child: ListView.builder( itemCount: _eligibleMembers.length, itemBuilder: (context, index) { final member = _eligibleMembers[index]; return ListTile( leading: CircleAvatar( backgroundColor: Colors.purple.shade100, child: Text( (member['name']?.isNotEmpty == true ? member['name'].substring(0, 1) : 'M').toUpperCase(), style: TextStyle( color: Colors.purple.shade700, fontWeight: FontWeight.w600, ), ), ), title: Text( member['name'], style: TextStyle(fontWeight: FontWeight.w500), ), subtitle: Text(member['mobile']), trailing: Icon( Icons.check_circle, color: Colors.green.shade600, size: 20.w, ), ); }, ), ), ], ), ); } Widget _buildDrawInProgress() { return Column( children: [ Text( 'Choose Your Draw Animation', style: TextStyle( fontSize: 20.sp, fontWeight: FontWeight.bold, color: Colors.purple.shade700, ), ), SizedBox(height: 16.h), Text( 'Select the animation type that works best for your group size', textAlign: TextAlign.center, style: TextStyle( fontSize: 14.sp, color: Colors.grey.shade600, height: 1.4, ), ), SizedBox(height: 24.h), Center( child: DrawAnimationSelector( members: _eligibleMembers, onDrawComplete: (winnerId) { final winner = _eligibleMembers.firstWhere((m) => m['id'] == winnerId); _onDrawComplete(winnerId, winner); }, serverSeed: _serverSeed, clientSeed: null, nonce: _nonce, animationDuration: const Duration(seconds: 4), ), ), ], ); } Widget _buildDrawResult() { return Column( children: [ // Winner Announcement Container( padding: EdgeInsets.all(20.w), decoration: BoxDecoration( color: Colors.green.shade50, borderRadius: BorderRadius.circular(12.r), border: Border.all(color: Colors.green.shade200), ), child: Column( children: [ Icon( Icons.emoji_events, color: Colors.amber.shade600, size: 48.w, ), SizedBox(height: 16.h), Text( 'Winner Selected!', style: TextStyle( fontSize: 20.sp, fontWeight: FontWeight.bold, color: Colors.green.shade800, ), ), SizedBox(height: 8.h), Text( _winnerData?['name'] ?? 'Unknown', style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.w600, color: Colors.green.shade700, ), ), SizedBox(height: 4.h), Text( _winnerData?['mobile'] ?? '', style: TextStyle( fontSize: 14.sp, color: Colors.grey.shade600, ), ), ], ), ), SizedBox(height: 16.h), // Quick Info Container( padding: EdgeInsets.all(12.w), decoration: BoxDecoration( color: Colors.blue.shade50, borderRadius: BorderRadius.circular(8.r), border: Border.all(color: Colors.blue.shade200), ), child: Row( children: [ Icon(Icons.security, color: Colors.blue.shade600, size: 16.w), SizedBox(width: 8.w), Expanded( child: Text( 'Draw completed using provably fair system. Recording saved.', style: TextStyle( fontSize: 12.sp, color: Colors.blue.shade700, ), ), ), ], ), ), ], ); } Future _saveDrawResult() async { setState(() => _isLoading = true); try { final month = int.parse(_monthController.text); final year = int.parse(_yearController.text); final success = await ChitGroupService.to.createMonthlyDraw( widget.group.id, month, year, clientSeed: null, ); if (success) { Navigator.of(context).pop(); Get.snackbar( 'Success', 'Monthly draw completed successfully!', backgroundColor: Colors.green.shade600, colorText: Colors.white, snackPosition: SnackPosition.TOP, ); } else { Get.snackbar( 'Error', 'Failed to save draw result. Please try again.', backgroundColor: Colors.red.shade600, colorText: Colors.white, snackPosition: SnackPosition.TOP, ); } } catch (e) { Get.snackbar( 'Error', 'An error occurred: $e', backgroundColor: Colors.red.shade600, colorText: Colors.white, snackPosition: SnackPosition.TOP, ); } finally { setState(() => _isLoading = false); } } }