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

class AnimatedDrawWheel extends StatefulWidget {
  final List<Map<String, dynamic>> members;
  final Function(String winnerId) onDrawComplete;
  final String? serverSeed;
  final String? clientSeed;
  final int? nonce;
  
  const AnimatedDrawWheel({
    super.key,
    required this.members,
    required this.onDrawComplete,
    this.serverSeed,
    this.clientSeed,
    this.nonce,
  });

  @override
  State<AnimatedDrawWheel> createState() => _AnimatedDrawWheelState();
}

class _AnimatedDrawWheelState extends State<AnimatedDrawWheel>
    with TickerProviderStateMixin {
  late AnimationController _spinController;
  late AnimationController _pulseController;
  late Animation<double> _spinAnimation;
  late Animation<double> _pulseAnimation;
  
  bool _isSpinning = false;
  bool _isDrawComplete = false;
  String? _winnerId;
  int _selectedIndex = 0;
  
  @override
  void initState() {
    super.initState();
    
    _spinController = AnimationController(
      duration: const Duration(seconds: 4),
      vsync: this,
    );
    
    _pulseController = AnimationController(
      duration: const Duration(milliseconds: 1000),
      vsync: this,
    );
    
    _spinAnimation = Tween<double>(
      begin: 0,
      end: 1,
    ).animate(CurvedAnimation(
      parent: _spinController,
      curve: Curves.easeOut,
    ));
    
    _pulseAnimation = Tween<double>(
      begin: 1.0,
      end: 1.2,
    ).animate(CurvedAnimation(
      parent: _pulseController,
      curve: Curves.easeInOut,
    ));
    
    _spinController.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        _completeDraw();
      }
    });
    
    // Auto-start the draw after a short delay
    Future.delayed(const Duration(milliseconds: 500), () {
      if (mounted) {
        _startDraw();
      }
    });
  }

  @override
  void dispose() {
    _spinController.dispose();
    _pulseController.dispose();
    super.dispose();
  }

  void _startDraw() {
    if (_isSpinning) return;
    
    print('🎰 Starting draw animation...');
    
    setState(() {
      _isSpinning = true;
      _isDrawComplete = false;
    });
    
    // Calculate the winner using provably fair algorithm
    _calculateWinner();
    
    print('🎯 Winner calculated: ${_winnerId} (index: $_selectedIndex)');
    
    // Start spinning animation
    _spinController.forward();
    _pulseController.repeat(reverse: true);
  }

  void _calculateWinner() {
    // Use provably fair algorithm to determine winner
    final serverSeed = widget.serverSeed ?? 'default_server_seed';
    final clientSeed = widget.clientSeed ?? 'default_client_seed';
    final nonce = widget.nonce ?? DateTime.now().millisecondsSinceEpoch;
    
    // Create a deterministic hash from the seeds and nonce
    final combinedSeed = '$serverSeed:$clientSeed:$nonce';
    final hash = _generateHash(combinedSeed);
    
    // Convert hash to a number and select winner
    final randomValue = _hashToNumber(hash);
    _selectedIndex = randomValue % widget.members.length;
    _winnerId = widget.members[_selectedIndex]['id'];
  }

  String _generateHash(String input) {
    // Simple hash function for demonstration
    // In production, use a proper cryptographic hash
    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) {
      // Pad with zeros if hash is too short
      hash = hash.padRight(10, '0');
    }
    return int.parse(hash.substring(0, 10));
  }

  void _completeDraw() {
    print('🎉 Draw completed! Winner: $_winnerId');
    
    setState(() {
      _isSpinning = false;
      _isDrawComplete = true;
    });
    
    _pulseController.stop();
    _pulseController.reset();
    
    // Notify parent of the winner
    if (_winnerId != null) {
      widget.onDrawComplete(_winnerId!);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 400.w,
      height: 400.w,
      child: Stack(
        alignment: Alignment.center,
        children: [
          // Outer ring
          Container(
            width: 400.w,
            height: 400.w,
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              border: Border.all(
                color: Colors.purple.shade300,
                width: 8.w,
              ),
              boxShadow: [
                BoxShadow(
                  color: Colors.purple.shade200,
                  blurRadius: 20.r,
                  spreadRadius: 5.r,
                ),
              ],
            ),
          ),
          
          // Spinning wheel
          AnimatedBuilder(
            animation: _spinAnimation,
            builder: (context, child) {
              return Transform.rotate(
                angle: _spinAnimation.value * 2 * math.pi * 5 + 
                       (_selectedIndex * 2 * math.pi / widget.members.length),
                child: Container(
                  width: 360.w,
                  height: 360.w,
                  decoration: BoxDecoration(
                    shape: BoxShape.circle,
                    gradient: RadialGradient(
                      colors: [
                        Colors.purple.shade50,
                        Colors.purple.shade100,
                        Colors.purple.shade200,
                      ],
                    ),
                  ),
                  child: CustomPaint(
                    painter: WheelPainter(
                      members: widget.members,
                      selectedIndex: _isDrawComplete ? _selectedIndex : -1,
                    ),
                  ),
                ),
              );
            },
          ),
          
          // Center circle with pointer
          Container(
            width: 80.w,
            height: 80.w,
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              color: Colors.white,
              border: Border.all(color: Colors.purple.shade400, width: 3.w),
              boxShadow: [
                BoxShadow(
                  color: Colors.black.withOpacity(0.1),
                  blurRadius: 10.r,
                  offset: Offset(0, 5.h),
                ),
              ],
            ),
            child: Icon(
              Icons.casino,
              color: Colors.purple.shade600,
              size: 40.w,
            ),
          ),
          
          // Pointer arrow
          Positioned(
            top: 20.h,
            child: Container(
              width: 0,
              height: 0,
              child: CustomPaint(
                painter: PointerPainter(),
                size: Size(20.w, 40.h),
              ),
            ),
          ),
          
          // Winner highlight
          if (_isDrawComplete)
            AnimatedBuilder(
              animation: _pulseAnimation,
              builder: (context, child) {
                return Transform.scale(
                  scale: _pulseAnimation.value,
                  child: Container(
                    width: 400.w,
                    height: 400.w,
                    decoration: BoxDecoration(
                      shape: BoxShape.circle,
                      border: Border.all(
                        color: Colors.green.shade400,
                        width: 4.w,
                      ),
                    ),
                  ),
                );
              },
            ),
        ],
      ),
    );
  }
}

class WheelPainter extends CustomPainter {
  final List<Map<String, dynamic>> members;
  final int selectedIndex;
  
  WheelPainter({
    required this.members,
    required this.selectedIndex,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final center = Offset(size.width / 2, size.height / 2);
    final radius = size.width / 2 - 20;
    
    final paint = Paint()
      ..style = PaintingStyle.fill;
    
    final textPainter = TextPainter(
      textDirection: TextDirection.ltr,
      textAlign: TextAlign.center,
    );
    
    for (int i = 0; i < members.length; i++) {
      final startAngle = (i * 2 * math.pi / members.length) - math.pi / 2;
      final sweepAngle = 2 * math.pi / members.length;
      
      // Color based on selection
      if (i == selectedIndex) {
        paint.color = Colors.green.shade300;
      } else {
        paint.color = (i % 2 == 0) 
            ? Colors.purple.shade100 
            : Colors.purple.shade200;
      }
      
      // Draw segment
      canvas.drawArc(
        Rect.fromCircle(center: center, radius: radius),
        startAngle,
        sweepAngle,
        true,
        paint,
      );
      
      // Draw member name
      final memberName = members[i]['name'] ?? 'Member ${i + 1}';
      final text = TextSpan(
        text: memberName.length > 8 ? '${memberName.substring(0, 8)}...' : memberName,
        style: TextStyle(
          color: Colors.purple.shade800,
          fontSize: 12.sp,
          fontWeight: FontWeight.w600,
        ),
      );
      
      textPainter.text = text;
      textPainter.layout();
      
      final textAngle = startAngle + sweepAngle / 2;
      final textRadius = radius * 0.7;
      final textX = center.dx + textRadius * math.cos(textAngle) - textPainter.width / 2;
      final textY = center.dy + textRadius * math.sin(textAngle) - textPainter.height / 2;
      
      canvas.save();
      canvas.translate(textX, textY);
      canvas.rotate(textAngle + math.pi / 2);
      textPainter.paint(canvas, Offset.zero);
      canvas.restore();
    }
  }

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

class PointerPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.red.shade600
      ..style = PaintingStyle.fill;
    
    final path = Path();
    path.moveTo(size.width / 2, 0);
    path.lineTo(0, size.height);
    path.lineTo(size.width, size.height);
    path.close();
    
    canvas.drawPath(path, paint);
  }

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