/* eslint-disable jsx-a11y/alt-text */
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
import {
  ImgHTMLAttributes,
  useCallback,
  useMemo,
  memo,
  useState,
  useEffect,
} from 'react'

import {cn} from '../../lib/utils'
import {getThumbhashDataURL, getResizedImageUrl} from '../../utils'

type ImageProps = ImgHTMLAttributes<HTMLImageElement> & {
  src?: string
  file?: File
  thumbhash?: string | null
  aspectRatio?: number | string
  objectFit?: 'cover' | 'contain' | 'fill' | 'scale-down' | 'none'
}

export const Image = memo(function Image(props: ImageProps) {
  const {
    src,
    file,
    thumbhash,
    onLoad,
    className,
    style,
    aspectRatio = 'auto',
    objectFit = 'contain',
    ...restProps
  } = props

  const [isLoaded, setIsLoaded] = useState(false)
  const [blobUrl, setBlobUrl] = useState<string | null>(null)

  // Create and manage blob URL for File objects
  useEffect(() => {
    if (!file) {
      setBlobUrl(null)
      return
    }

    const url = URL.createObjectURL(file)
    setBlobUrl(url)

    // Cleanup on unmount or when file changes
    return () => {
      URL.revokeObjectURL(url)
    }
  }, [file])

  const thumbhashDataURL = useMemo(
    () => getThumbhashDataURL(thumbhash ?? undefined),
    [thumbhash]
  )

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

  // Use blob URL if file is provided, otherwise use src
  const imageSrc = useMemo(() => {
    if (blobUrl) return blobUrl
    return getResizedImageUrl(src)
  }, [blobUrl, src])

  return (
    <div
      className={cn('relative w-full', className)}
      style={{
        ...style,
        ...(aspectRatio !== 'auto' && {aspectRatio}),
        backgroundImage: thumbhashDataURL
          ? `url(${thumbhashDataURL})`
          : undefined,
        backgroundSize: 'cover',
        backgroundPosition: 'center',
      }}
    >
      <img
        className={cn(
          aspectRatio === 'auto'
            ? 'opacity-0 w-full h-auto'
            : 'absolute inset-0 opacity-0 size-full',
          `object-${objectFit}`,
          isLoaded && 'opacity-100'
        )}
        src={imageSrc}
        onLoad={handleLoad}
        {...restProps}
      />
    </div>
  )
})
