import * as Amplitude from 'expo-analytics-amplitude'
import { isString } from 'lodash'
import React, { useState } from 'react'
import { StyleProp, ImageStyle, Image } from 'react-native'

import { colors } from '../Colors'
import { CachedImage } from './CachedImage'
import { ImageGradientBackground } from './ImageGradientBackground'

type Props = {
  uris: string[]
  cacheKey: string
  gradientString: string
  style?: StyleProp<ImageStyle>
}

/**
 *
 * CachedImageWithFallback will try the following in order:
 * download the image to the local filesystem and
 * in the case we cannot cache images, and if that fails, fallback to the image gradient.
 *
 * Why this logic? Issue was surfaced in the BrowserStack environment,
 * where the iOS build did not have necessary filesystem
 * permissions to cache the images manually.
 */
export function CachedImageWithFallback({
  uris,
  cacheKey,
  gradientString,
  style,
}: Props): React.ReactElement {
  const [hasCachedImage, setHasCachedImage] = useState(true)
  const [hasImage, setHasImage] = useState(true)

  if (hasCachedImage) {
    Amplitude.logEventWithPropertiesAsync('cached_image_cached', {
      cacheKey,
      uris,
    })
    return (
      <CachedImage
        uris={uris}
        cacheKey={cacheKey}
        onError={() => setHasCachedImage(false)}
        style={style}
        loadingStyle={{ backgroundColor: colors.metals.metal3 }}
      />
    )
  }

  const uri = uris.filter(isString)[0]

  if (uri != null && hasImage) {
    Amplitude.logEventWithPropertiesAsync('cached_image_original', {
      cacheKey,
      uris,
    })
    return (
      <Image
        source={{ uri }}
        style={style}
        onError={() => setHasImage(false)}
      />
    )
  }

  Amplitude.logEventWithPropertiesAsync('cached_image_gradient', {
    cacheKey,
    uris,
  })

  return <ImageGradientBackground string={gradientString} style={style} />
}
