import React, { memo, useEffect, useState } from 'react'
import { Image } from 'react-native'
import deepEqual from 'fast-deep-equal/es6'
import { getBlurhash } from 'utils/blurhash'
import { ImageBlurhashProps } from 'types'
import { getBitmapBlurhash } from 'utils/images'

const ImageBlurhash = ({
  object,
  source,
  componentProps,
  layout,
}: ImageBlurhashProps) => {
  const [uri, setUri] = useState<string | null>(null)

  const blurhash = getBlurhash(object, source, componentProps)
  const { blurHash, blurHashWidth, blurHashHeight, resizeMode } = blurhash ?? {}

  useEffect(() => {
    let blurhashUri: string

    async function fetchUri(
      blurHash: string,
      blurHashWidth: number,
      blurHashHeight: number
    ) {
      const blob = await getBitmapBlurhash(
        blurHash,
        blurHashWidth,
        blurHashHeight
      )

      blurhashUri = URL.createObjectURL(blob)

      setUri(blurhashUri)
    }

    try {
      if (!blurHash || !blurHashWidth || !blurHashHeight) {
        throw new Error('precondition failed')
      }

      fetchUri(blurHash, blurHashWidth, blurHashHeight)
    } catch (error) { /* no-op */ } // prettier-ignore

    return () => {
      if (blurhashUri) {
        URL.revokeObjectURL(blurhashUri)
      }
    }
  }, [blurHash, blurHashWidth, blurHashHeight])

  if (!layout || !uri) {
    return null
  }

  const { width, height } = layout

  return (
    <Image source={{ uri }} style={{ width, height }} resizeMode={resizeMode} />
  )
}

export default memo(ImageBlurhash, deepEqual)
