import PropTypes from 'prop-types'
import { useState, useEffect, useMemo, useCallback, memo } from 'react'
import Particles, { initParticlesEngine } from '@tsparticles/react'
import { loadSlim } from '@tsparticles/slim'
import { useThemeContext } from '../Dashboard/context/ThemeContext'

const ParticlesComponent = memo(({ options, particlesLoaded }) => {
  return (
    <Particles
      id='tsparticles'
      options={options}
      particlesLoaded={particlesLoaded}
    />
  )
})

ParticlesComponent.displayName = 'ParticlesComponent'

const AppParticles = () => {
  const [init, setInit] = useState(false)
  const { isDarkMode } = useThemeContext()

  // this should be run only once per application lifetime
  useEffect(() => {
    initParticlesEngine(async (engine) => {
      await loadSlim(engine)
    }).then(() => {
      setInit(true)
    })
  }, [])

  const particlesLoaded = useCallback(() => {}, [])

  const options = useMemo(
    () => ({
      background: {
        color: {
          value: isDarkMode ? '#000000' : '#ffffff'
        }
      },
      fpsLimit: 120,
      interactivity: {
        events: {
          onClick: {
            enable: true,
            mode: 'push'
          },
          onHover: {
            enable: true,
            mode: 'repulse'
          }
        },
        modes: {
          push: {
            quantity: 4
          },
          repulse: {
            distance: 200,
            duration: 0.4
          }
        }
      },
      particles: {
        color: {
          value: isDarkMode ? 'rgb(66, 66, 66)' : 'rgb(217, 217, 217)'
        },
        links: {
          color: isDarkMode ? 'rgb(66, 66, 66)' : 'rgb(217, 217, 217)',
          distance: 150,
          enable: true,
          opacity: 0.5,
          width: 1
        },
        move: {
          direction: 'none',
          enable: true,
          outModes: {
            default: 'bounce'
          },
          random: false,
          speed: 1,
          straight: false
        },
        number: {
          density: {
            enable: true
          },
          value: 160
        },
        opacity: {
          value: 0.5
        },
        shape: {
          type: 'circle'
        },
        size: {
          value: { min: 1, max: 5 }
        }
      },
      detectRetina: true
    }),
    [isDarkMode]
  )
  return (
    <>
      {init && (
        <ParticlesComponent
          options={options}
          particlesLoaded={particlesLoaded}
        />
      )}
    </>
  )
}

ParticlesComponent.propTypes = {
  options: PropTypes.object.isRequired,
  particlesLoaded: PropTypes.func.isRequired
}

export default AppParticles
