import { useState, useCallback, memo } from 'react';
import { cn } from '@/lib/utils';

interface ResponsiveImageProps extends React.ImgHTMLAttributes<HTMLImageElement> {
    /** Image source URL */
    src: string;
    /** Alt text for accessibility */
    alt: string;
    /** Width of the image (required to prevent CLS) */
    width: number;
    /** Height of the image (required to prevent CLS) */
    height: number;
    /** Additional CSS classes */
    className?: string;
    /** Whether to use priority loading (for LCP images) */
    priority?: boolean;
    /** Placeholder color while loading */
    placeholderColor?: string;
    /** Object fit style */
    objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down';
    /** Sizes attribute for responsive images */
    sizes?: string;
    /** WebP source URL for modern browsers */
    srcSetWebp?: string;
    /** SrcSet for responsive images */
    srcSet?: string;
}

/**
 * ResponsiveImage Component
 * 
 * Optimized image component that prevents layout shift (CLS) and 
 * reduces forced reflows. Use this instead of regular <img> tags.
 * 
 * @example
 * ```tsx
 * <ResponsiveImage
 *   src="/logo.png"
 *   alt="Logo"
 *   width={1280}
 *   height={720}
 *   priority
 *   className="w-8 h-auto"
 * />
 * ```
 */
export const ResponsiveImage = memo(function ResponsiveImage({
    src,
    alt,
    width,
    height,
    className,
    priority = false,
    placeholderColor = '#f3f4f6',
    objectFit = 'cover',
    sizes,
    srcSetWebp,
    srcSet,
    style,
    onLoad,
    ...props
}: ResponsiveImageProps) {
    const [isLoaded, setIsLoaded] = useState(false);
    const [hasError, setHasError] = useState(false);

    // Calculate aspect ratio to prevent layout shift
    const aspectRatio = width / height;

    const handleLoad = useCallback((e: React.SyntheticEvent<HTMLImageElement>) => {
        setIsLoaded(true);
        onLoad?.(e);
    }, [onLoad]);

    const handleError = useCallback(() => {
        setHasError(true);
    }, []);

    // Don't render if error and no fallback handling
    if (hasError && !props.onError) {
        return (
            <div
                className={cn("bg-gray-200 flex items-center justify-center", className)}
                style={{
                    width: width,
                    height: height,
                    aspectRatio: aspectRatio,
                    ...style,
                }}
                role="img"
                aria-label={alt}
            >
                <span className="text-gray-400 text-sm">Failed to load</span>
            </div>
        );
    }

    const imageProps: React.ImgHTMLAttributes<HTMLImageElement> = {
        src,
        alt,
        width,
        height,
        loading: priority ? 'eager' : 'lazy',
        decoding: priority ? 'sync' : 'async',
        onLoad: handleLoad,
        onError: handleError,
        className: cn(
            "transition-opacity duration-300",
            isLoaded ? "opacity-100" : "opacity-0",
            className
        ),
        style: {
            objectFit,
            ...style,
        },
        ...props,
    };

    return (
        <div
            className="relative overflow-hidden"
            style={{
                aspectRatio: aspectRatio,
                backgroundColor: placeholderColor,
                // Prevent layout shift during load
                contain: 'layout',
            }}
        >
            {srcSetWebp ? (
                <picture>
                    <source
                        srcSet={srcSetWebp}
                        type="image/webp"
                        sizes={sizes}
                    />
                    <source
                        srcSet={srcSet}
                        sizes={sizes}
                    />
                    <img {...imageProps} />
                </picture>
            ) : (
                <img {...imageProps} />
            )}
        </div>
    );
});

/**
 * LogoImage Component
 * 
 * Specialized component for logo images with common optimizations.
 * Automatically handles resizing for smaller display sizes.
 */
interface LogoImageProps {
    src: string;
    alt: string;
    /** Display width in pixels (actual rendered size) */
    displayWidth?: number;
    /** Display height in pixels (actual rendered size) */
    displayHeight?: number;
    className?: string;
    priority?: boolean;
}

export const LogoImage = memo(function LogoImage({
    src,
    alt,
    displayWidth = 32,
    displayHeight = 32,
    className,
    priority = false,
}: LogoImageProps) {
    // Use the display dimensions to prevent loading oversized images
    // This helps with the "Image file is larger than it needs to be" warning
    return (
        <ResponsiveImage
            src={src}
            alt={alt}
            width={displayWidth}
            height={displayHeight}
            priority={priority}
            className={cn("object-contain", className)}
            style={{
                width: displayWidth,
                height: displayHeight,
            }}
            objectFit="contain"
        />
    );
});

/**
 * LazyImage Component
 * 
 * Image that only loads when it enters the viewport.
 * Uses IntersectionObserver for efficient lazy loading.
 */
interface LazyImageProps extends Omit<ResponsiveImageProps, 'priority'> {
    /** Root margin for intersection observer */
    rootMargin?: string;
    /** Threshold for intersection observer */
    threshold?: number;
}

export const LazyImage = memo(function LazyImage({
    rootMargin: _rootMargin = '50px',
    threshold: _threshold = 0.01,
    ...props
}: LazyImageProps) {
    // This component could be enhanced with IntersectionObserver
    // for more advanced lazy loading behavior
    return <ResponsiveImage {...props} priority={false} />;
});

export default ResponsiveImage;
