import React, { useState, useCallback } from 'react'
import { useSpring } from 'react-spring'
import { usePrefersReducedMotion } from './usePrefersReducedMotion'
// Heavily inspired by Josh Comeau: https://www.joshwcomeau.com/react/boop/ 💖

// Wiggle function accepts various parameters specifying properties for the animation
export function useWiggle({
  x = 0,
  y = 0,
  rotation = 0,
  scale = 1,
  timing = 150,
  springConfig = {
    tension: 300,
    friction: 10,
  },
}) {
  // Accessibility setting from the user system indicating that they prefer to minimize motion
  const prefersReducedMotion = usePrefersReducedMotion()

  // Declare state variable isActive, set initially to false
  const [isActive, setIsActive] = useState(false)

  // We offload the actual animation to spring: https://www.react-spring.io/docs/hooks/use-spring
  const style = useSpring({
    transform: isActive
      ? `translate(${x}px, ${y}px) rotate(${rotation}deg) scale(${scale})`
      : `translate(0px, 0px) rotate(0deg) scale(1)`,
    config: springConfig,
  })

  // Timing parameter determines how long the wiggle lasts using browser setTimeout function
  // React useEffect function https://reactjs.org/docs/hooks-effect.html
  React.useEffect(() => {
    if (!isActive) {
      return
    }
    const timeoutId = window.setTimeout(() => {
      setIsActive(false)
    }, timing)
    return () => {
      window.clearTimeout(timeoutId)
    }
  }, [isActive]) // Continue wiggle until isActive is set false when timeout elapses

  // Set wiggle to active when the triggering event occurs - will be set false when effect completes above
  const trigger = useCallback(() => {
    setIsActive(true)
  }, [])

  let appliedStyle = prefersReducedMotion ? {} : style

  // Return animation style effect and function to apply on trigger in page
  return [appliedStyle, trigger]
}
