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

class Particle {
  Offset position;
  Offset velocity;
  Color color;
  double size;
  double life; // 1.0 to 0.0
  double decay;

  Particle({
    required this.position,
    required this.velocity,
    required this.color,
    required this.size,
    required this.life,
    required this.decay,
  });
}

class ExplosionWidget extends StatefulWidget {
  const ExplosionWidget({super.key});

  @override
  ExplosionWidgetState createState() => ExplosionWidgetState();
}

class ExplosionWidgetState extends State<ExplosionWidget>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  final List<Particle> _particles = [];
  final Random _random = Random();

  bool get isAnimating => _controller.isAnimating || _particles.isNotEmpty;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 1000),
    );
    _controller.addListener(_updateParticles);
  }

  @override
  void dispose() {
    _controller.removeListener(_updateParticles);
    _controller.dispose();
    super.dispose();
  }

  void _updateParticles() {
    if (_particles.isEmpty) return;

    for (var i = _particles.length - 1; i >= 0; i--) {
      final p = _particles[i];
      p.position += p.velocity;
      p.velocity += Offset(0, 0.5); // Gravity
      p.life -= p.decay;
      if (p.life <= 0) {
        _particles.removeAt(i);
      }
    }

    if (_particles.isEmpty) {
      _controller.stop();
    }
    setState(() {});
  }

  void explode(Offset position) {
    // Clear old particles if any (optional, or just add more)
    // _particles.clear();

    // Create new particles
    for (int i = 0; i < 30; i++) {
      final double angle = _random.nextDouble() * 2 * pi;
      final double speed = _random.nextDouble() * 5 + 2;
      final double dx = cos(angle) * speed;
      final double dy = sin(angle) * speed;

      // Random colors for fire/explosion effect
      Color color;
      final r = _random.nextDouble();
      if (r < 0.33) {
        color = Colors.redAccent;
      } else if (r < 0.66) {
        color = Colors.orangeAccent;
      } else {
        color = Colors.yellowAccent;
      }

      _particles.add(
        Particle(
          position: position,
          velocity: Offset(dx, dy),
          color: color,
          size: _random.nextDouble() * 4 + 2,
          life: 1.0,
          decay: _random.nextDouble() * 0.02 + 0.01,
        ),
      );
    }

    if (!_controller.isAnimating) {
      _controller.repeat(); // Use repeat to keep loop running until empty
    }
  }

  @override
  Widget build(BuildContext context) {
    return IgnorePointer(
      child: CustomPaint(
        painter: ExplosionPainter(_particles),
        size: Size.infinite,
      ),
    );
  }
}

class ExplosionPainter extends CustomPainter {
  final List<Particle> particles;

  ExplosionPainter(this.particles);

  @override
  void paint(Canvas canvas, Size size) {
    for (final p in particles) {
      final paint = Paint()
        ..color = p.color.withValues(alpha: p.life.clamp(0.0, 1.0))
        ..style = PaintingStyle.fill;

      canvas.drawCircle(p.position, p.size, paint);
    }
  }

  @override
  bool shouldRepaint(covariant ExplosionPainter oldDelegate) {
    return true; // Always repaint when animating
  }
}
