/* 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 {getThumbhashBlobURL, getResizedImageUrl} from '../../utils'

/**
 * An optimized image component that handles File objects, remote URLs, blob URL lifecycle management, and progressive loading with thumbhash placeholders. Ideal for displaying images from useImagePicker or any remote source.
 * @publicDocs
 */
export interface ImageDocProps {
  /** Remote image URL */
  src?: string
  /** File object from useImagePicker (auto-manages blob URL lifecycle) */
  file?: File
  /** Thumbhash string for progressive loading placeholder */
  thumbhash?: string | null
  /** Aspect ratio (e.g., 16/9, "4/3", or "auto") */
  aspectRatio?: number | string
  /** How the image should fit within its container */
  objectFit?: 'cover' | 'contain' | 'fill' | 'scale-down' | 'none'
  /** Alt text for accessibility */
  alt?: string
  /** Callback when image finishes loading */
  onLoad?: () => void
}

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 thumbhashBlobUrl = useMemo(
    () => getThumbhashBlobURL(thumbhash ?? undefined),
    [thumbhash]
  )

  // Cleanup blob URL when it changes or component unmounts
  useEffect(() => {
    return () => {
      if (thumbhashBlobUrl) {
        URL.revokeObjectURL(thumbhashBlobUrl)
      }
    }
  }, [thumbhashBlobUrl])

  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}),
      }}
    >
      {thumbhashBlobUrl && !isLoaded && (
        <img
          className={cn(
            aspectRatio === 'auto'
              ? 'w-full h-auto'
              : 'absolute inset-0 size-full',
            'object-cover'
          )}
          src={thumbhashBlobUrl}
          aria-hidden="true"
        />
      )}
      <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>
  )
})
