"use client";

import React, { useState, useEffect, useRef, ReactNode } from 'react';
import Image from 'next/image';

interface OptimizedLazyLoadProps {
  children: ReactNode;
  fallback?: ReactNode;
  rootMargin?: string;
  threshold?: number;
  once?: boolean;
  className?: string;
  onVisible?: () => void;
  delay?: number; // Delay before loading in ms
}

/**
 * Optimized lazy loading wrapper with intersection observer
 * and performance optimizations
 */
export function OptimizedLazyLoad({
  children,
  fallback,
  rootMargin = '100px',
  threshold = 0.1,
  once = true,
  className,
  onVisible,
  delay = 0
}: OptimizedLazyLoadProps) {
  const [isLoaded, setIsLoaded] = useState(false);
  const elementRef = useRef<HTMLDivElement>(null);
  const observerRef = useRef<IntersectionObserver | null>(null);
  const timeoutRef = useRef<NodeJS.Timeout | null>(null);

  useEffect(() => {
    const currentElement = elementRef.current;
    if (!currentElement) return;

    // Create intersection observer
    observerRef.current = new IntersectionObserver(
      (entries) => {
        const [entry] = entries;
        if (entry.isIntersecting) {
          onVisible?.();

          if (delay > 0) {
            timeoutRef.current = setTimeout(() => {
              setIsLoaded(true);
            }, delay);
          } else {
            setIsLoaded(true);
          }

          if (once) {
            observerRef.current?.unobserve(currentElement);
          }
        } else if (!once) {
          if (timeoutRef.current) {
            clearTimeout(timeoutRef.current);
          }
        }
      },
      {
        rootMargin,
        threshold,
      }
    );

    observerRef.current.observe(currentElement);

    return () => {
      if (observerRef.current) {
        observerRef.current.unobserve(currentElement);
        observerRef.current.disconnect();
      }
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }
    };
  }, [rootMargin, threshold, once, onVisible, delay]);

  return (
    <div ref={elementRef} className={className}>
      {isLoaded ? children : fallback}
    </div>
  );
}

/**
 * Skeleton loader for lazy loaded content
 */
export function LazyLoadSkeleton({ 
  height = '200px', 
  className = '' 
}: { 
  height?: string; 
  className?: string; 
}) {
  return (
    <div 
      className={`animate-pulse bg-gray-200 rounded-lg ${className}`}
      style={{ height }}
    >
      <div className="flex items-center justify-center h-full">
        <div className="text-gray-400 text-sm">Loading...</div>
      </div>
    </div>
  );
}

/**
 * Image lazy loading with optimization
 */
interface OptimizedImageProps {
  src: string;
  alt: string;
  width?: number;
  height?: number;
  className?: string;
  loading?: 'lazy' | 'eager';
  onLoad?: () => void;
  onError?: () => void;
  fallbackSrc?: string;
}

export function OptimizedImage({
  src,
  alt,
  width,
  height,
  className = '',
  loading = 'lazy',
  onLoad,
  onError,
  fallbackSrc = '/assets/placeholder-product.jpg'
}: OptimizedImageProps) {
  const [isLoaded, setIsLoaded] = useState(false);
  const [hasError, setHasError] = useState(false);
  const [currentSrc, setCurrentSrc] = useState(src);

  const handleLoad = () => {
    setIsLoaded(true);
    onLoad?.();
  };

  const handleError = () => {
    if (!hasError && fallbackSrc && currentSrc !== fallbackSrc) {
      setCurrentSrc(fallbackSrc);
      setHasError(true);
    }
    onError?.();
  };

  return (
    <div className={`relative overflow-hidden ${className}`} style={{ width, height }}>
      {!isLoaded && (
        <div className="absolute inset-0 bg-gray-200 animate-pulse flex items-center justify-center">
          <div className="text-gray-400 text-xs">Loading...</div>
        </div>
      )}
      <Image
        src={currentSrc}
        alt={alt}
        fill
        unoptimized
        loading={loading}
        onLoad={handleLoad}
        onError={handleError}
        className={`transition-opacity duration-300 ${
          isLoaded ? 'opacity-100' : 'opacity-0'
        } ${className}`}
        style={{
          objectFit: 'contain',
        }}
      />
    </div>
  );
}