import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'dart:math' as math;
import 'dart:async';

class ParticleDrawAnimation extends StatefulWidget {
  final List<Map<String, dynamic>> members;
  final Function(String winnerId) onDrawComplete;
  final String? serverSeed;
  final String? clientSeed;
  final int? nonce;
  final Duration animationDuration;

  const ParticleDrawAnimation({
    super.key,
    required this.members,
    required this.onDrawComplete,
    this.serverSeed,
    this.clientSeed,
    this.nonce,
    this.animationDuration = const Duration(seconds: 5),
  });

  @override
  State<ParticleDrawAnimation> createState() => _ParticleDrawAnimationState();
}

class _ParticleDrawAnimationState extends State<ParticleDrawAnimation>
    with TickerProviderStateMixin {
  late AnimationController _particleController;
  late AnimationController _winnerController;
  late Animation<double> _particleAnimation;
  late Animation<double> _winnerAnimation;
  
  bool _isAnimating = false;
  bool _isComplete = false;
  String? _winnerId;
  Map<String, dynamic>? _winnerData;
  List<Particle> _particles = [];
  Timer? _particleTimer;

  @override
  void initState() {
    super.initState();
    
    _particleController = AnimationController(
      duration: widget.animationDuration,
      vsync: this,
    );
    
    _winnerController = AnimationController(
      duration: const Duration(milliseconds: 1000),
      vsync: this,
    );
    
    _particleAnimation = Tween<double>(
      begin: 0,
      end: 1,
    ).animate(CurvedAnimation(
      parent: _particleController,
      curve: Curves.easeInOut,
    ));
    
    _winnerAnimation = Tween<double>(
      begin: 0,
      end: 1,
    ).animate(CurvedAnimation(
      parent: _winnerController,
      curve: Curves.elasticOut,
    ));
    
    _particleController.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        _completeAnimation();
      }
    });
    
    // Auto-start after delay
    Future.delayed(const Duration(milliseconds: 500), () {
      if (mounted) _startAnimation();
    });
  }

  @override
  void dispose() {
    _particleController.dispose();
    _winnerController.dispose();
    _particleTimer?.cancel();
    super.dispose();
  }

  void _startAnimation() {
    if (_isAnimating) return;
    
    setState(() {
      _isAnimating = true;
    });
    
    _calculateWinner();
    _generateParticles();
    _particleController.forward();
  }

  void _calculateWinner() {
    final serverSeed = widget.serverSeed ?? 'default_server_seed';
    final clientSeed = widget.clientSeed ?? 'default_client_seed';
    final nonce = widget.nonce ?? DateTime.now().millisecondsSinceEpoch;
    
    final combinedSeed = '$serverSeed:$clientSeed:$nonce';
    final hash = _generateHash(combinedSeed);
    final randomValue = _hashToNumber(hash);
    final selectedIndex = randomValue % widget.members.length;
    
    _winnerId = widget.members[selectedIndex]['id'];
    _winnerData = widget.members[selectedIndex];
  }

  void _generateParticles() {
    _particles.clear();
    final random = math.Random();
    
    // Generate particles for each member
    for (int i = 0; i < widget.members.length; i++) {
      final member = widget.members[i];
      final isWinner = member['id'] == _winnerId;
      
      // Create multiple particles per member
      for (int j = 0; j < (isWinner ? 20 : 5); j++) {
        _particles.add(Particle(
          id: '${member['id']}_$j',
          memberId: member['id'],
          memberName: member['name'] ?? 'Unknown',
          x: random.nextDouble() * 300.w,
          y: random.nextDouble() * 400.h,
          vx: (random.nextDouble() - 0.5) * 2,
          vy: (random.nextDouble() - 0.5) * 2,
          size: random.nextDouble() * 8 + 4,
          color: isWinner 
              ? Colors.green.shade400
              : Colors.primaries[random.nextInt(Colors.primaries.length)].shade400,
          isWinner: isWinner,
        ));
      }
    }
  }

  void _completeAnimation() {
    setState(() {
      _isAnimating = false;
      _isComplete = true;
    });
    
    _winnerController.forward();
    widget.onDrawComplete(_winnerId!);
  }

  String _generateHash(String input) {
    int hash = 0;
    for (int i = 0; i < input.length; i++) {
      hash = ((hash << 5) - hash + input.codeUnitAt(i)) & 0xffffffff;
    }
    return hash.abs().toString();
  }

  int _hashToNumber(String hash) {
    if (hash.length < 10) {
      hash = hash.padRight(10, '0');
    }
    return int.parse(hash.substring(0, 10));
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 300.w,
      height: 400.h,
      child: Column(
        children: [
          // Title
          Text(
            'Particle Draw',
            style: TextStyle(
              fontSize: 20.sp,
              fontWeight: FontWeight.bold,
              color: Colors.indigo.shade700,
            ),
          ),
          SizedBox(height: 20.h),
          
          // Particle Display
          Expanded(
            child: Container(
              width: 280.w,
              height: 300.h,
              decoration: BoxDecoration(
                color: Colors.black,
                borderRadius: BorderRadius.circular(16.r),
                border: Border.all(color: Colors.indigo.shade400, width: 2.w),
              ),
              child: AnimatedBuilder(
                animation: _particleAnimation,
                builder: (context, child) {
                  return CustomPaint(
                    painter: ParticlePainter(
                      particles: _particles,
                      animationValue: _particleAnimation.value,
                      isComplete: _isComplete,
                    ),
                    size: Size(280.w, 300.h),
                  );
                },
              ),
            ),
          ),
          
          // Winner Display
          if (_isComplete)
            AnimatedBuilder(
              animation: _winnerAnimation,
              builder: (context, child) {
                return Transform.scale(
                  scale: _winnerAnimation.value,
                  child: Container(
                    margin: EdgeInsets.only(top: 20.h),
                    padding: EdgeInsets.all(16.w),
                    decoration: BoxDecoration(
                      gradient: LinearGradient(
                        colors: [Colors.green.shade400, Colors.green.shade600],
                      ),
                      borderRadius: BorderRadius.circular(12.r),
                      boxShadow: [
                        BoxShadow(
                          color: Colors.green.shade300,
                          blurRadius: 10.r,
                          offset: Offset(0, 5.h),
                        ),
                      ],
                    ),
                    child: Column(
                      children: [
                        Icon(
                          Icons.emoji_events,
                          color: Colors.white,
                          size: 32.w,
                        ),
                        SizedBox(height: 8.h),
                        Text(
                          'WINNER!',
                          style: TextStyle(
                            fontSize: 18.sp,
                            fontWeight: FontWeight.bold,
                            color: Colors.white,
                          ),
                        ),
                        Text(
                          _winnerData?['name'] ?? 'Unknown',
                          style: TextStyle(
                            fontSize: 16.sp,
                            color: Colors.white.withOpacity(0.9),
                          ),
                        ),
                      ],
                    ),
                  ),
                );
              },
            )
          else if (_isAnimating)
            Container(
              margin: EdgeInsets.only(top: 20.h),
              child: Text(
                'Particles swirling...',
                style: TextStyle(
                  fontSize: 16.sp,
                  color: Colors.indigo.shade600,
                ),
              ),
            ),
        ],
      ),
    );
  }
}

class Particle {
  final String id;
  final String memberId;
  final String memberName;
  double x;
  double y;
  double vx;
  double vy;
  final double size;
  final Color color;
  final bool isWinner;

  Particle({
    required this.id,
    required this.memberId,
    required this.memberName,
    required this.x,
    required this.y,
    required this.vx,
    required this.vy,
    required this.size,
    required this.color,
    required this.isWinner,
  });

  void update() {
    x += vx;
    y += vy;
    
    // Bounce off walls
    if (x <= 0 || x >= 280) vx = -vx;
    if (y <= 0 || y >= 300) vy = -vy;
    
    // Keep particles in bounds
    x = x.clamp(0, 280);
    y = y.clamp(0, 300);
  }
}

class ParticlePainter extends CustomPainter {
  final List<Particle> particles;
  final double animationValue;
  final bool isComplete;

  ParticlePainter({
    required this.particles,
    required this.animationValue,
    required this.isComplete,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()..style = PaintingStyle.fill;
    
    for (final particle in particles) {
      // Update particle position
      particle.update();
      
      // Apply animation effects
      final alpha = isComplete && particle.isWinner 
          ? 1.0 
          : (0.3 + 0.7 * animationValue);
      
      paint.color = particle.color.withOpacity(alpha);
      
      // Draw particle
      canvas.drawCircle(
        Offset(particle.x, particle.y),
        particle.size * (isComplete && particle.isWinner ? 1.5 : 1.0),
        paint,
      );
      
      // Draw member name for winner particles
      if (isComplete && particle.isWinner) {
        final textPainter = TextPainter(
          text: TextSpan(
            text: particle.memberName.length > 8 
                ? '${particle.memberName.substring(0, 8)}...' 
                : particle.memberName,
            style: TextStyle(
              color: Colors.white,
              fontSize: 10,
              fontWeight: FontWeight.bold,
            ),
          ),
          textDirection: TextDirection.ltr,
        );
        textPainter.layout();
        textPainter.paint(
          canvas,
          Offset(
            particle.x - textPainter.width / 2,
            particle.y + particle.size + 5,
          ),
        );
      }
    }
    
    // Draw connecting lines for winner particles
    if (isComplete) {
      final winnerParticles = particles.where((p) => p.isWinner).toList();
      if (winnerParticles.isNotEmpty) {
        paint.color = Colors.green.withOpacity(0.3);
        paint.strokeWidth = 2;
        paint.style = PaintingStyle.stroke;
        
        for (int i = 0; i < winnerParticles.length - 1; i++) {
          canvas.drawLine(
            Offset(winnerParticles[i].x, winnerParticles[i].y),
            Offset(winnerParticles[i + 1].x, winnerParticles[i + 1].y),
            paint,
          );
        }
      }
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
