import * as React from "react";
import { Image as RnImage, ImageStyle } from "react-native";
import * as R from "ramda";

import { useImageSource } from "./hooks";

type Source = {
  uri: string;
};

type Props = Record<string, any> & {
  style: ImageStyle;
  uri?: string;
  placeholderImage?: string;

  entry?: ZappEntry | ZappFeed;
  withDimensions: (source: Source) => Source;
};

const MemoizedImage = React.memo(RnImage, R.equals);

function Image({
  style,
  uri,
  placeholderImage,
  entry,
  withDimensions,
  ...otherProps
}: Props) {
  const [error, setErrorState] = React.useState(null);

  const source = useImageSource({ uri, entry, otherProps });

  React.useEffect(() => {
    // reset error state on URI change as the error is referencing previous uri
    setErrorState(null);
  }, [uri]);

  const shouldRenderImg = source && !error;

  // Default placeholder image fallback is empty string because it won't rerender
  // in case of undefined or {uri: undefined} source
  // https://github.com/facebook/react-native/issues/9195
  const defaultPlaceHolderImage = React.useMemo(
    () => ({ uri: placeholderImage || "" }),
    [source, error]
  );

  return (
    // @ts-ignore
    <MemoizedImage
      style={style as ImageStyle}
      onError={React.useCallback(() => setErrorState(true), [])}
      source={
        shouldRenderImg ? withDimensions(source) : defaultPlaceHolderImage
      }
      {...R.omit(["source"], otherProps)}
    />
  );
}

export default Image;
