'use client';

import { useEffect, useState, RefObject } from 'react';

/**
 * Calculate scroll progress (0-1) based on element's position in viewport
 * @param ref - Reference to the element to track
 * @param offset - Offset from viewport edges (0-1, default 0.1)
 * @returns progress value between 0 and 1
 */
export function useScrollProgress(ref: RefObject<HTMLElement | null>, offset: number = 0.1): number {
  const [progress, setProgress] = useState(0);

  useEffect(() => {
    if (!ref.current) return;

    let rafId: number;
    
    const calculateProgress = () => {
      if (!ref.current) return;

      const rect = ref.current.getBoundingClientRect();
      const viewportHeight = window.innerHeight;
      const scrollY = window.scrollY;
      const documentHeight = document.documentElement.scrollHeight;
      
      // Element enters viewport from bottom
      const enterPoint = viewportHeight * (1 - offset);
      // Element reaches top of viewport
      const exitPoint = viewportHeight * offset;
      
      // Calculate progress: 0 when entering, 1 at 30% viewport (accelerated)
      const elementCenter = rect.top + rect.height / 2;
      const totalDistance = enterPoint - exitPoint;
      const currentDistance = enterPoint - elementCenter;
      
      // Accelerate progress to reach 1.0 at 30% viewport height
      // Scale factor: 1.67 makes progress reach 1.0 at ~30% instead of 50%
      const rawProgress = (currentDistance / totalDistance) * 1.67;
      let clampedProgress = Math.max(0, Math.min(1, rawProgress));
      
      // At bottom of page - ensure elements near bottom can reach 100%
      // Only apply if we're at the very bottom AND this element is below the fold
      if (scrollY + viewportHeight >= documentHeight - 50 && rect.top < viewportHeight) {
        clampedProgress = Math.max(clampedProgress, 1);
      }
      
      setProgress(clampedProgress);
    };

    const handleScroll = () => {
      if (rafId) {
        cancelAnimationFrame(rafId);
      }
      rafId = requestAnimationFrame(calculateProgress);
    };

    // Initial calculation
    calculateProgress();

    window.addEventListener('scroll', handleScroll, { passive: true });
    window.addEventListener('resize', handleScroll, { passive: true });

    return () => {
      window.removeEventListener('scroll', handleScroll);
      window.removeEventListener('resize', handleScroll);
      if (rafId) {
        cancelAnimationFrame(rafId);
      }
    };
  }, [ref, offset]);

  return progress;
}

/**
 * Calculate parallax offset based on scroll position
 * @param ref - Reference to the element to track
 * @param speed - Parallax speed multiplier (default 0.5)
 * @returns offset in pixels
 */
export function useParallax(ref: RefObject<HTMLElement | null>, speed: number = 0.5): number {
  const [offset, setOffset] = useState(0);

  useEffect(() => {
    if (!ref.current) return;

    let rafId: number;
    
    const calculateOffset = () => {
      if (!ref.current) return;

      const rect = ref.current.getBoundingClientRect();
      const viewportHeight = window.innerHeight;
      
      // Calculate offset based on element position relative to viewport
      const scrolled = viewportHeight - rect.top;
      const parallaxOffset = scrolled * speed;
      
      setOffset(parallaxOffset);
    };

    const handleScroll = () => {
      if (rafId) {
        cancelAnimationFrame(rafId);
      }
      rafId = requestAnimationFrame(calculateOffset);
    };

    calculateOffset();

    window.addEventListener('scroll', handleScroll, { passive: true });
    window.addEventListener('resize', handleScroll, { passive: true });

    return () => {
      window.removeEventListener('scroll', handleScroll);
      window.removeEventListener('resize', handleScroll);
      if (rafId) {
        cancelAnimationFrame(rafId);
      }
    };
  }, [ref, speed]);

  return offset;
}