'use client'

import React, { useEffect, useRef, useState } from 'react'
import { cn } from '@/lib/utils/cn'
import { motion } from 'framer-motion'

interface FadeInTextProps {
  text: string
  className?: string
  delayBeforeStart?: number
  canAnimate?: boolean
}

export const FadeInText: React.FC<FadeInTextProps> = ({
  text,
  className,
  delayBeforeStart = 0,
  canAnimate = true,
}) => {
  const words = (text || '').split(' ')
  const [visibleCount, setVisibleCount] = useState(0)
  const [hasBeenVisible, setHasBeenVisible] = useState(false)
  const containerRef = useRef<HTMLSpanElement>(null)

  useEffect(() => {
    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          setHasBeenVisible(true)
          observer.disconnect()
        }
      },
      { threshold: 0.3 }
    )

    if (containerRef.current) {
      observer.observe(containerRef.current)
    }

    return () => {
      observer.disconnect()
    }
  }, [])

  useEffect(() => {
    if (!canAnimate || !hasBeenVisible) {
      setVisibleCount(0)
      return
    }

    setVisibleCount(0)
    const timeouts: NodeJS.Timeout[] = []

    const delayTimeout = setTimeout(() => {
      for (let i = 0; i < words.length; i++) {
        const timeout = setTimeout(() => {
          setVisibleCount((prev) => Math.max(prev, i + 1))
        }, i * 300)
        timeouts.push(timeout)
      }
    }, delayBeforeStart)

    timeouts.push(delayTimeout)

    return () => timeouts.forEach(clearTimeout)
  }, [hasBeenVisible])

  return (
    <span ref={containerRef} className={cn('inline-block', className)}>
      {words.map((word, i) => (
        <motion.span
          key={i}
          initial={{ opacity: 0, y: 10 }}
          animate={i < visibleCount ? { opacity: 1, y: 0 } : { opacity: 0, y: 10 }}
          transition={{
            duration: 0.5,
            ease: [0.4, 0, 0.2, 1],
          }}
          className="inline-block"
        >
          {word}
          {i !== words.length - 1 && '\u00A0'}
        </motion.span>
      ))}
    </span>
  )
}

export default FadeInText
