'use client';

import { useEffect, useLayoutEffect, useRef, useState, type ReactNode } from 'react';
import { clsx } from 'clsx';

type Variant = 'up' | 'down' | 'fade' | 'scale';

export function Reveal({
  children,
  className,
  variant = 'up',
  delay = 0,
  as: Tag = 'div'
}: {
  children: ReactNode;
  className?: string;
  variant?: Variant;
  delay?: number;
  as?: 'div' | 'section' | 'li' | 'span' | 'p';
}) {
  const ref = useRef<HTMLElement | null>(null);
  const [state, setState] = useState<'off' | 'revealing' | 'in'>('off');

  useLayoutEffect(() => {
    setState('revealing');
  }, []);

  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    if (!('IntersectionObserver' in window)) {
      setState('in');
      return;
    }
    const io = new IntersectionObserver(
      (entries) => {
        for (const entry of entries) {
          if (entry.isIntersecting) {
            setState('in');
            io.disconnect();
          }
        }
      },
      { rootMargin: '0px 0px -60px 0px', threshold: 0.12 }
    );
    io.observe(el);
    return () => io.disconnect();
  }, []);

  return (
    <Tag
      ref={ref as never}
      data-variant={variant}
      className={clsx(state !== 'off' && 'reveal', state === 'in' && 'is-in', className)}
      style={state !== 'off' ? { transitionDelay: `${delay}ms` } : undefined}
    >
      {children}
    </Tag>
  );
}