import React, { useEffect, useRef } from 'react';
import { styled } from '@mui/system';
import './NoiseBackground.scss'; // Import the SCSS file here

const NoiseWrapper = styled('div')`
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  z-index: -1;
  pointer-events: none;
`;

const loadScript = (src) => {
  return new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.src = src;
    script.onload = resolve;
    script.onerror = reject;
    document.head.appendChild(script);
  });
};

const NoiseBackground = ({ children }) => {
  const canvasRef = useRef(null);

  useEffect(() => {
    const initialize = async () => {
      await loadScript('https://rawgithub.com/jwagner/simplex-noise.js/master/simplex-noise.js');
      const noise = new window.SimplexNoise();
      const canvas = canvasRef.current;
      const ctx = canvas.getContext('2d');

      const resizeCanvas = () => {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
      };

      resizeCanvas();
      window.addEventListener('resize', resizeCanvas);

      const TAU = Math.PI * 2;
      const THIRD = 1 / 3;
      const TWO_THIRDS = 2 / 3;
      const ZERO = 0;
      const ONE = 1;

      const map = (value, start1, stop1, start2, stop2) => {
        return start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1));
      };

      const background = (fillStyle) => {
        ctx.fillStyle = fillStyle;
        ctx.fillRect(0, 0, canvas.width, canvas.height);
      };

      const beginPath = () => {
        ctx.beginPath();
      };

      const moveTo = (x, y) => {
        ctx.moveTo(x, y);
      };

      const lineTo = (x, y) => {
        ctx.lineTo(x, y);
      };

      const compositeOperation = (operation) => {
        ctx.globalCompositeOperation = operation;
      };

      const stroke = (strokeStyle, lineWidth) => {
        ctx.strokeStyle = strokeStyle;
        ctx.lineWidth = lineWidth;
        ctx.stroke();
      };

      const hsl = (h, s, l, a = 1) => `hsla(${h},${s}%,${l}%,${a})`;

      const draw = (e) => {
        const width = canvas.width;
        const height = canvas.height;
        const width_half = width / 2;
        const height_half = height / 2;

        let xCount = 35;
        let yCount = 80;
        let iXCount = 1 / (xCount - 1);
        let iYCount = 1 / (yCount - 1);
        let time = e * 0.001;
        let timeStep = 0.01;
        let grad = ctx.createLinearGradient(-width, 0, width, height);
        let t = time % 1;
        let tSide = Math.floor(time % 2) === 0;
        let hueA = tSide ? 340 : 210;
        let hueB = !tSide ? 340 : 210;
        let colorA = hsl(hueA, 100, 50);
        let colorB = hsl(hueB, 100, 50);
        grad.addColorStop(map(t, 0, 1, ZERO, THIRD), colorA);
        grad.addColorStop(map(t, 0, 1, THIRD, TWO_THIRDS), colorB);
        grad.addColorStop(map(t, 0, 1, TWO_THIRDS, ONE), colorA);
        ctx.globalAlpha = map(Math.cos(time), -1, 1, 0.15, 0.3);
        background(grad);
        ctx.globalAlpha = 1;
        beginPath();
        for (let j = 0; j < yCount; j++) {
          let tj = j * iYCount;
          let c = Math.cos(tj * TAU + time) * 0.1;
          for (let i = 0; i < xCount; i++) {
            let t = i * iXCount;
            let n = noise.noise3D(t, time, c);
            let y = n * height_half;
            let x = t * (width + 20) - width_half - 10;
            (i ? lineTo : moveTo)(x, y);
          }
          time += timeStep;
        }
        compositeOperation('lighter');
        ctx.filter = 'blur(10px)';
        stroke(grad, 5);
        ctx.filter = 'blur(5px)';
        stroke(hsl(0, 0, 100, 0.8), 2);
      };

      const animate = (time) => {
        draw(time);
        requestAnimationFrame(animate);
      };

      requestAnimationFrame(animate);

      return () => {
        window.removeEventListener('resize', resizeCanvas);
      };
    };

    initialize();
  }, []);

  return (
    <NoiseWrapper>
      <canvas ref={canvasRef}></canvas>
      {children}
    </NoiseWrapper>
  );
};

export default NoiseBackground;
