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

import '../../domain/game/game.dart';
import '../theme/theme.dart';

class WheelPainter extends CustomPainter {
  final List<GamePrize> gamePrizes;
  final Color Function(GamePrize prize, int index) getPrizeColor;

  WheelPainter({required this.gamePrizes, required this.getPrizeColor});

  @override
  void paint(Canvas canvas, Size size) {
    if (gamePrizes.isEmpty) return;

    final center = Offset(size.width / 2, size.height / 2);
    final radius = size.width / 2;
    final sectionAngle = 2 * math.pi / gamePrizes.length;

    // Draw outer white border
    final outerBorderPaint = Paint()
      ..color = Colors.white
      ..style = PaintingStyle.fill;
    canvas.drawCircle(center, radius, outerBorderPaint);

    // Draw blue border ring
    final blueBorderPaint = Paint()
      ..color = const Color(0xFF3B82F6)
      ..style = PaintingStyle.fill;
    canvas.drawCircle(center, radius - 8, blueBorderPaint);

    // Draw inner white circle
    final innerWhitePaint = Paint()
      ..color = Colors.white
      ..style = PaintingStyle.fill;
    canvas.drawCircle(center, radius - 20, innerWhitePaint);

    // Draw sections
    for (int i = 0; i < gamePrizes.length; i++) {
      final prize = gamePrizes[i];
      final startAngle = i * sectionAngle - math.pi / 2;

      // Section background
      final sectionPaint = Paint()
        ..color = getPrizeColor(prize, i)
        ..style = PaintingStyle.fill;

      canvas.drawArc(
        Rect.fromCircle(center: center, radius: radius - 22),
        startAngle,
        sectionAngle,
        true,
        sectionPaint,
      );

      // Draw icon in each section
      final iconAngle = startAngle + sectionAngle / 2;
      final iconPosition = Offset(
        center.dx + (radius - 60) * math.cos(iconAngle),
        center.dy + (radius - 60) * math.sin(iconAngle),
      );

      // Draw icon background circle
      final iconBgPaint = Paint()
        ..color = Colors.white
        ..style = PaintingStyle.fill;
      canvas.drawCircle(iconPosition, 16, iconBgPaint);

      // Save canvas state for icon drawing
      canvas.save();
      canvas.translate(iconPosition.dx, iconPosition.dy);

      // Get icon from metadata or use default
      final iconData = _getIconFromMetadata(prize.metadata);
      final iconText = _getIconText(iconData);
      final iconTextPainter = TextPainter(
        text: TextSpan(
          text: iconText,
          style: TextStyle(
            fontFamily: 'MaterialIcons',
            fontSize: 20,
            color: getPrizeColor(prize, i),
            fontWeight: FontWeight.normal,
          ),
        ),
        textDirection: TextDirection.ltr,
      );
      iconTextPainter.layout();
      iconTextPainter.paint(
        canvas,
        Offset(-iconTextPainter.width / 2, -iconTextPainter.height / 2),
      );

      canvas.restore();

      // Draw prize text
      final textAngle = startAngle + sectionAngle / 2;
      final textPosition = Offset(
        center.dx + (radius - 100) * math.cos(textAngle),
        center.dy + (radius - 100) * math.sin(textAngle),
      );

      // Save canvas state for text rotation
      canvas.save();
      canvas.translate(textPosition.dx, textPosition.dy);
      canvas.rotate(textAngle + math.pi / 2);

      final textPainter = TextPainter(
        text: TextSpan(
          text: prize.name,
          style: const TextStyle(
            color: Colors.white,
            fontSize: 10,
            fontWeight: FontWeight.bold,
          ),
        ),
        textDirection: TextDirection.ltr,
      );
      textPainter.layout();
      textPainter.paint(
        canvas,
        Offset(-textPainter.width / 2, -textPainter.height / 2),
      );

      canvas.restore();

      // Draw stock indicator if stock is low
      if (prize.stock <= 5 && prize.stock > 0) {
        final stockAngle = startAngle + sectionAngle / 2;
        final stockPosition = Offset(
          center.dx + (radius - 35) * math.cos(stockAngle),
          center.dy + (radius - 35) * math.sin(stockAngle),
        );

        final stockPaint = Paint()
          ..color = AppColor.error
          ..style = PaintingStyle.fill;
        canvas.drawCircle(stockPosition, 8, stockPaint);

        canvas.save();
        canvas.translate(stockPosition.dx, stockPosition.dy);

        final stockTextPainter = TextPainter(
          text: TextSpan(
            text: '!',
            style: const TextStyle(
              color: Colors.white,
              fontSize: 10,
              fontWeight: FontWeight.bold,
            ),
          ),
          textDirection: TextDirection.ltr,
        );
        stockTextPainter.layout();
        stockTextPainter.paint(
          canvas,
          Offset(-stockTextPainter.width / 2, -stockTextPainter.height / 2),
        );

        canvas.restore();
      }
    }

    // Draw white dots around the outer edge
    final dotPaint = Paint()
      ..color = Colors.white
      ..style = PaintingStyle.fill;

    for (int i = 0; i < 24; i++) {
      final dotAngle = (2 * math.pi / 24) * i;
      final dotPosition = Offset(
        center.dx + (radius - 14) * math.cos(dotAngle),
        center.dy + (radius - 14) * math.sin(dotAngle),
      );
      canvas.drawCircle(dotPosition, 3, dotPaint);
    }

    // Draw section dividers
    final dividerPaint = Paint()
      ..color = AppColor.white
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2;

    for (int i = 0; i < gamePrizes.length; i++) {
      final angle = i * sectionAngle - math.pi / 2;
      final lineStart = Offset(
        center.dx + (radius - 130) * math.cos(angle),
        center.dy + (radius - 130) * math.sin(angle),
      );
      final lineEnd = Offset(
        center.dx + (radius - 22) * math.cos(angle),
        center.dy + (radius - 22) * math.sin(angle),
      );
      canvas.drawLine(lineStart, lineEnd, dividerPaint);
    }
  }

  IconData _getIconFromMetadata(Map<String, dynamic> metadata) {
    final iconName = metadata['icon'] as String?;
    switch (iconName?.toLowerCase()) {
      case 'card_giftcard':
        return Icons.card_giftcard;
      case 'monetization_on':
        return Icons.monetization_on;
      case 'redeem':
        return Icons.redeem;
      case 'attach_money':
        return Icons.attach_money;
      case 'account_balance_wallet':
        return Icons.account_balance_wallet;
      case 'diamond':
        return Icons.diamond;
      case 'star':
        return Icons.star;
      case 'emoji_events':
        return Icons.emoji_events;
      case 'refresh':
        return Icons.refresh;
      case 'visibility':
        return Icons.visibility;
      default:
        return Icons.card_giftcard; // Default icon
    }
  }

  String _getIconText(IconData icon) {
    // Convert IconData to Unicode string for drawing
    switch (icon.codePoint) {
      case 0xe8f4: // Icons.visibility
        return String.fromCharCode(0xe8f4);
      case 0xe8f5: // Icons.visibility_off
        return String.fromCharCode(0xe8f5);
      case 0xe850: // Icons.account_balance_wallet
        return String.fromCharCode(0xe850);
      case 0xe151: // Icons.card_giftcard
        return String.fromCharCode(0xe151);
      case 0xe5d5: // Icons.refresh
        return String.fromCharCode(0xe5d5);
      case 0xe263: // Icons.attach_money
        return String.fromCharCode(0xe263);
      case 0xe8a1: // Icons.redeem
        return String.fromCharCode(0xe8a1);
      case 0xe57d: // Icons.monetization_on
        return String.fromCharCode(0xe57d);
      case 0xe5ca: // Icons.diamond
        return String.fromCharCode(0xe5ca);
      case 0xe838: // Icons.star
        return String.fromCharCode(0xe838);
      case 0xe2a3: // Icons.emoji_events
        return String.fromCharCode(0xe2a3);
      default:
        return String.fromCharCode(0xe151); // Default card_giftcard icon
    }
  }

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