import { clsx } from 'clsx';
import { useRef, useCallback } from 'react';

import { useHasIntersected } from '../common/hooks';

export interface ImageProps {
  alt: string;
  src: string;
  id?: string;
  onLoad?: () => void;
  onError?: () => void;
  className?: string;
  /**
   * Specifies the [loading behavior of the image](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/img#loading).
   */
  loading?: 'lazy' | 'eager';
  stretch?: boolean;
  role?: string;
  shrink?: boolean;
}

const Image = ({
  id,
  src,
  alt,
  onLoad,
  onError,
  className,
  loading,
  stretch = true,
  role,
  shrink = true,
}: ImageProps) => {
  const elementReference = useRef<HTMLImageElement>(null);
  const [hasIntersected] = useHasIntersected({ elRef: elementReference, loading });

  // Internal onLoad handler that calls user onLoad only if hasIntersected is true
  const handleLoad = useCallback(() => {
    if (hasIntersected && onLoad) {
      onLoad();
    }
  }, [hasIntersected, onLoad]);

  return (
    <img
      ref={elementReference}
      id={id}
      alt={alt}
      src={src}
      loading={loading}
      className={clsx([
        'tw-image',
        {
          'tw-image__stretch': stretch,
          'tw-image__shrink': shrink,
        },
        className,
      ])}
      role={role}
      onLoad={handleLoad}
      onError={onError}
    />
  );
};

export default Image;
