'use client'

import { CSSProperties, useMemo, useState, useRef, useEffect } from 'react'
import { Media } from '@/payload-types'
import { cn } from '@/lib/utils/cn'

interface Props {
  media?: Media | string
  className?: string
  objectFit?: CSSProperties['objectFit']
  objectPosition?: CSSProperties['objectPosition']
  width?: number | string
  height?: number | string
  loading?: 'lazy' | 'eager'
  alt?: string
  style?: CSSProperties
}

export const ImageLoader: React.FC<Props> = ({
  media,
  className,
  objectFit = 'cover',
  objectPosition,
  width,
  height,
  loading = 'lazy',
  alt = '',
  style,
}) => {
  const [isLoaded, setIsLoaded] = useState(false)
  const imgRef = useRef<HTMLImageElement>(null)

  useEffect(() => {
    if (imgRef.current?.complete) {
      setIsLoaded(true)
    }
  }, [])

  const { src, altText, imgWidth, imgHeight } = useMemo(() => {
    if (!media) return { src: '', altText: '', imgWidth: undefined, imgHeight: undefined }
    if (typeof media === 'string') {
      return {
        src: media,
        altText: alt || '',
        imgWidth: width,
        imgHeight: height,
      }
    }
    return {
      src: media.url || media.thumbnailURL || '',
      altText: alt || media.alt || '',
      imgWidth: width || media.width || undefined,
      imgHeight: height || media.height || undefined,
    }
  }, [media, alt, width, height])

  const aspectRatio =
    typeof imgWidth === 'number' && typeof imgHeight === 'number' && imgHeight > 0
      ? `${imgWidth} / ${imgHeight}`
      : '16 / 9'

  if (!src) return null

  return (
    <img
      ref={imgRef}
      src={src}
      alt={altText}
      width={width}
      height={height}
      loading={loading}
      onLoad={() => setIsLoaded(true)}
      className={cn(
        className,
        'transition-opacity duration-500',
        isLoaded ? 'opacity-100' : 'opacity-0',
      )}
      style={{ objectFit, objectPosition, aspectRatio, ...style }}
    />
  )
}

export default ImageLoader
