'use client'
import { cn } from '@/lib/utils'
import { motion, useInView } from 'motion/react'
import * as React from 'react'

type StaggeredFadeProps = {
  text: string
  className?: string
}

export const StaggeredFade: React.FC<StaggeredFadeProps> = ({ text, className = '' }) => {
  const ref = React.useRef<HTMLSpanElement>(null)
  const isInView = useInView(ref, { once: true })
  const [fallbackVisible, setFallbackVisible] = React.useState(false)
  const shouldShow = isInView || fallbackVisible

  React.useEffect(() => {
    if (isInView || fallbackVisible) return

    let frame = 0

    const checkVisibility = () => {
      cancelAnimationFrame(frame)
      frame = requestAnimationFrame(() => {
        const element = ref.current
        if (!element) return

        const bounds = element.getBoundingClientRect()
        const viewportHeight = window.innerHeight || document.documentElement.clientHeight
        if (bounds.top < viewportHeight * 0.95 && bounds.bottom > viewportHeight * 0.05) {
          setFallbackVisible(true)
        }
      })
    }

    checkVisibility()
    window.addEventListener('scroll', checkVisibility, { passive: true })
    window.addEventListener('resize', checkVisibility)

    return () => {
      cancelAnimationFrame(frame)
      window.removeEventListener('scroll', checkVisibility)
      window.removeEventListener('resize', checkVisibility)
    }
  }, [fallbackVisible, isInView])

  const variants = {
    hidden: { opacity: 0 },
    show: (i: number) => ({
      opacity: 1,
      transition: { delay: i * 0.05 },
    }),
  }

  return (
    <motion.span
      ref={ref}
      initial='hidden'
      viewport={{ once: false, amount: 0.3 }}
      animate={shouldShow ? 'show' : 'hidden'}
      className={cn('inline-block', className)}
    >
      {text.split('').map((char, i) => (
        <motion.span key={i} variants={variants} custom={i}>
          {char === ' ' ? '\u00A0' : char}
        </motion.span>
      ))}
    </motion.span>
  )
}
