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/models/chit_group.dart'; import '../../shared/widgets/draw_animation_selector.dart'; class DrawAnimationPage extends StatefulWidget { final ChitGroup group; final int month; final int year; final String serverSeed; final int nonce; final List> eligibleMembers; const DrawAnimationPage({ super.key, required this.group, required this.month, required this.year, required this.serverSeed, required this.nonce, required this.eligibleMembers, }); @override State createState() => _DrawAnimationPageState(); } class _DrawAnimationPageState extends State with SingleTickerProviderStateMixin { late AnimationController _fadeController; late Animation _fadeAnimation; bool _isComplete = false; @override void initState() { super.initState(); _fadeController = AnimationController( duration: const Duration(milliseconds: 800), vsync: this, ); _fadeAnimation = Tween( begin: 0.0, end: 1.0, ).animate(CurvedAnimation( parent: _fadeController, curve: Curves.easeInOut, )); _fadeController.forward(); } @override void dispose() { _fadeController.dispose(); super.dispose(); } void _onDrawComplete(String winnerId) async { if (_isComplete) return; setState(() { _isComplete = true; }); // Wait a moment to show the winner await Future.delayed(const Duration(seconds: 3)); // Save the draw result final chitGroupService = Get.find(); try { await chitGroupService.createMonthlyDraw( widget.group.id, widget.month, widget.year, clientSeed: 'DRAW_${DateTime.now().millisecondsSinceEpoch}', ); // Navigate back with success Get.back(result: true); Get.snackbar( 'Draw Complete! 🎉', 'Winner has been selected successfully', backgroundColor: Colors.green, colorText: Colors.white, duration: const Duration(seconds: 3), snackPosition: SnackPosition.TOP, ); } catch (e) { Get.back(result: false); Get.snackbar( 'Error', 'Failed to save draw result: ${e.toString()}', backgroundColor: Colors.red, colorText: Colors.white, duration: const Duration(seconds: 4), ); } } @override Widget build(BuildContext context) { return WillPopScope( onWillPop: () async { // Prevent back button during animation if (_isComplete) return true; final result = await showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Cancel Draw?'), content: const Text('Are you sure you want to cancel the draw? This action cannot be undone.'), actions: [ TextButton( onPressed: () => Navigator.pop(context, false), child: const Text('Continue Draw'), ), ElevatedButton( onPressed: () => Navigator.pop(context, true), style: ElevatedButton.styleFrom( backgroundColor: Colors.red, foregroundColor: Colors.white, ), child: const Text('Cancel Draw'), ), ], ), ); return result ?? false; }, child: Scaffold( backgroundColor: Colors.black, body: SafeArea( child: FadeTransition( opacity: _fadeAnimation, child: Container( width: double.infinity, height: double.infinity, decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ Colors.purple.shade900, Colors.blue.shade900, Colors.indigo.shade900, ], ), ), child: Column( children: [ // Header Padding( padding: EdgeInsets.all(20.w), child: Column( children: [ Row( children: [ if (!_isComplete) IconButton( icon: Icon( Icons.close, color: Colors.white.withOpacity(0.8), size: 28.w, ), onPressed: () async { final result = await showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Cancel Draw?'), content: const Text('Are you sure you want to cancel the draw?'), actions: [ TextButton( onPressed: () => Navigator.pop(context, false), child: const Text('Continue'), ), ElevatedButton( onPressed: () => Navigator.pop(context, true), style: ElevatedButton.styleFrom( backgroundColor: Colors.red, foregroundColor: Colors.white, ), child: const Text('Cancel'), ), ], ), ); if (result == true) { Get.back(result: false); } }, ) else SizedBox(width: 48.w), Expanded( child: Column( children: [ Text( widget.group.name, style: TextStyle( fontSize: 24.sp, fontWeight: FontWeight.bold, color: Colors.white, ), textAlign: TextAlign.center, ), SizedBox(height: 8.h), Container( padding: EdgeInsets.symmetric( horizontal: 16.w, vertical: 6.h, ), decoration: BoxDecoration( color: Colors.white.withOpacity(0.2), borderRadius: BorderRadius.circular(20.r), border: Border.all( color: Colors.white.withOpacity(0.3), ), ), child: Text( 'Month ${widget.month}/${widget.year}', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: Colors.white, ), ), ), ], ), ), SizedBox(width: 48.w), ], ), ], ), ), // Animation Area Expanded( child: Center( child: DrawAnimationSelector( members: widget.eligibleMembers, onDrawComplete: _onDrawComplete, serverSeed: widget.serverSeed, clientSeed: 'DRAW_${DateTime.now().millisecondsSinceEpoch}', nonce: widget.nonce, animationDuration: const Duration(seconds: 8), ), ), ), // Footer Padding( padding: EdgeInsets.all(20.w), child: Column( children: [ Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: Colors.white.withOpacity(0.1), borderRadius: BorderRadius.circular(12.r), border: Border.all( color: Colors.white.withOpacity(0.2), ), ), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ _buildInfoItem( 'Eligible Members', '${widget.eligibleMembers.length}', Icons.people, ), Container( width: 1, height: 30.h, color: Colors.white.withOpacity(0.3), ), _buildInfoItem( 'Total Members', '${widget.group.maxMembers}', Icons.group, ), ], ), ], ), ), SizedBox(height: 12.h), Text( '🎲 Provably Fair Draw', style: TextStyle( fontSize: 14.sp, color: Colors.white.withOpacity(0.7), fontWeight: FontWeight.w500, ), ), ], ), ), ], ), ), ), ), ), ); } Widget _buildInfoItem(String label, String value, IconData icon) { return Column( children: [ Icon( icon, color: Colors.white.withOpacity(0.8), size: 24.w, ), SizedBox(height: 6.h), Text( value, style: TextStyle( fontSize: 20.sp, fontWeight: FontWeight.bold, color: Colors.white, ), ), Text( label, style: TextStyle( fontSize: 12.sp, color: Colors.white.withOpacity(0.7), ), ), ], ); } }