import React, { useEffect } from 'react';
import { styled } from '@mui/system';

const FireworksWrapper = styled('div')`
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  background: transparent;
  overflow: hidden;
`;

const FireworksBackground = ({ children }) => {
  useEffect(() => {
    const canvas = document.getElementById('fireworksCanvas');
    const ctx = canvas.getContext('2d');
    const fireworks = [];
    const particles = [];

    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    function Firework(x, y, targetX, targetY) {
      this.x = x;
      this.y = y;
      this.targetX = targetX;
      this.targetY = targetY;
      this.distanceToTarget = Math.sqrt((targetX - x) ** 2 + (targetY - y) ** 2);
      this.distanceTraveled = 0;
      this.coordinates = [];
      this.coordinateCount = 3;
      while (this.coordinateCount--) {
        this.coordinates.push([this.x, this.y]);
      }
      this.angle = Math.atan2(targetY - y, targetX - x);
      this.speed = 2;
      this.acceleration = 1.05;
      this.brightness = Math.random() * 30 + 50;
      this.targetRadius = 1;
    }

    Firework.prototype.update = function(index) {
      this.coordinates.pop();
      this.coordinates.unshift([this.x, this.y]);

      this.targetRadius = Math.sin(this.distanceTraveled / this.distanceToTarget * Math.PI) * 5;

      this.speed *= this.acceleration;

      const vx = Math.cos(this.angle) * this.speed;
      const vy = Math.sin(this.angle) * this.speed;
      this.distanceTraveled = Math.sqrt((this.x + vx - this.startX) ** 2 + (this.y + vy - this.startY) ** 2);

      if (this.distanceTraveled >= this.distanceToTarget) {
        createParticles(this.targetX, this.targetY);
        fireworks.splice(index, 1);
      } else {
        this.x += vx;
        this.y += vy;
      }
    };

    Firework.prototype.draw = function() {
      ctx.beginPath();
      ctx.moveTo(this.coordinates[this.coordinates.length - 1][0], this.coordinates[this.coordinates.length - 1][1]);
      ctx.lineTo(this.x, this.y);
      ctx.strokeStyle = `hsl(${Math.random() * 360}, 100%, ${this.brightness}%)`;
      ctx.stroke();
    };

    function Particle(x, y) {
      this.x = x;
      this.y = y;
      this.coordinates = [];
      this.coordinateCount = 5;
      while (this.coordinateCount--) {
        this.coordinates.push([this.x, this.y]);
      }
      this.angle = Math.random() * Math.PI * 2;
      this.speed = Math.random() * 10 + 1;
      this.friction = 0.95;
      this.gravity = 1;
      this.hue = Math.random() * 360;
      this.brightness = Math.random() * 50 + 50;
      this.alpha = 1;
      this.decay = Math.random() * 0.015 + 0.015;
    }

    Particle.prototype.update = function(index) {
      this.coordinates.pop();
      this.coordinates.unshift([this.x, this.y]);
      this.speed *= this.friction;
      this.x += Math.cos(this.angle) * this.speed;
      this.y += Math.sin(this.angle) * this.speed + this.gravity;
      this.alpha -= this.decay;

      if (this.alpha <= this.decay) {
        particles.splice(index, 1);
      }
    };

    Particle.prototype.draw = function() {
      ctx.beginPath();
      ctx.moveTo(this.coordinates[this.coordinates.length - 1][0], this.coordinates[this.coordinates.length - 1][1]);
      ctx.lineTo(this.x, this.y);
      ctx.strokeStyle = `hsla(${this.hue}, 100%, ${this.brightness}%, ${this.alpha})`;
      ctx.stroke();
    };

    function createParticles(x, y) {
      let particleCount = 30;
      while (particleCount--) {
        particles.push(new Particle(x, y));
      }
    }

    function loop() {
      requestAnimationFrame(loop);

      ctx.globalCompositeOperation = 'destination-out';
      ctx.fillStyle = `rgba(0, 0, 0, 0.5)`;
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      ctx.globalCompositeOperation = 'lighter';

      let i = fireworks.length;
      while (i--) {
        fireworks[i].draw();
        fireworks[i].update(i);
      }

      i = particles.length;
      while (i--) {
        particles[i].draw();
        particles[i].update(i);
      }
    }

    function random(min, max) {
      return Math.random() * (max - min) + min;
    }

    canvas.addEventListener('click', (e) => {
      const x = e.clientX;
      const y = e.clientY;
      const targetX = random(0, canvas.width);
      const targetY = random(0, canvas.height / 2);
      fireworks.push(new Firework(x, y, targetX, targetY));
    });

    loop();
  }, []);

  return (
    <FireworksWrapper>
      <canvas id="fireworksCanvas"></canvas>
      {children}
    </FireworksWrapper>
  );
};

export default FireworksBackground;
