"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _react = _interopRequireWildcard(require("react"));
var _reactNative = require("react-native");
var _cacheManager = _interopRequireDefault(require("./cache-manager"));
var _box = _interopRequireDefault(require("../../atoms/box/box"));
var _expoBlur = require("expo-blur");
var _spinner = _interopRequireDefault(require("../../atoms/spinner/spinner"));
var _pearl = require("../../../pearl");
var _center = _interopRequireDefault(require("../../atoms/center/center"));
var _styleFunctions = require("../../../theme/src/style-functions");
var _hooks = require("../../../hooks");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function usePrevious(value) {
  const ref = (0, _react.useRef)();
  (0, _react.useEffect)(() => {
    ref.current = value;
  });
  return ref.current;
}
const PearlRNImage = (0, _pearl.pearl)(_reactNative.Image, {
  componentName: "",
  type: "basic",
  animatable: true
});
const AnimatedView = _reactNative.Animated.createAnimatedComponent(_reactNative.View);
const AnimatedBlurView = _reactNative.Animated.createAnimatedComponent(_expoBlur.BlurView);
const PearlAnimatedBlurView = (0, _pearl.pearl)(AnimatedBlurView, {
  componentName: "",
  type: "basic",
  animatable: true
});
const PearlAnimatedView = (0, _pearl.pearl)(AnimatedView, {
  componentName: "",
  type: "basic",
  animatable: true
});
const previewColorStyleFunction = (0, _styleFunctions.createStyleFunction)({
  property: "previewColor",
  styleProperty: "previewColor",
  themeKey: "palette",
  transform: _styleFunctions.transformColorValue
});
const CustomImage = /*#__PURE__*/_react.default.memo( /*#__PURE__*/_react.default.forwardRef(({
  atoms
}, ref) => {
  const {
    source,
    onError,
    testID,
    fallbackSource,
    fallbackComponent,
    previewSource,
    imageDownloadOptions,
    isCached = true,
    loaderType = "spinner",
    tint = "dark",
    sourceDelay = 0,
    overlayTransitionDuration = 300,
    ...restImageProps
  } = atoms.image;
  const isRemoteImage = typeof source === "object";
  const shouldCache = isRemoteImage && isCached;
  const isMounted = (0, _react.useRef)(true);
  const [uri, setUri] = (0, _react.useState)(undefined);
  const [error, setError] = (0, _react.useState)(false);
  const previousUri = usePrevious(uri);
  const imageProps = (0, _hooks.useStyleProps)(atoms.image, [previewColorStyleFunction]);
  const {
    previewColor
  } = imageProps.style;
  const isImageReady = (0, _react.useMemo)(() => isRemoteImage ? !!uri : true, [isRemoteImage, uri]);
  const finalSource = (0, _react.useMemo)(() => isRemoteImage ? {
    ...source,
    uri: uri
  } : source, [isRemoteImage, source, uri]);
  const intensity = (0, _react.useRef)(new _reactNative.Animated.Value(100)).current;
  const previewSourceOverlayOpacity = intensity.interpolate({
    inputRange: [0, 100],
    outputRange: [0, 1]
  });
  const blurIntensity = intensity.interpolate({
    inputRange: [0, 100],
    outputRange: [0, 50]
  });
  const finalImageOpacity = intensity.interpolate({
    inputRange: [0, 100],
    outputRange: [1, 0.75]
  });
  const backwardCompatibleTintOverlayOpacity = intensity.interpolate({
    inputRange: [0, 100],
    outputRange: [0, 0.5]
  });
  const previewColorOverlayOpacity = intensity.interpolate({
    inputRange: [0, 100],
    outputRange: [0, 1]
  });
  const {
    borderRadius,
    borderBottomLeftRadius,
    borderBottomRightRadius,
    borderTopLeftRadius,
    borderTopRightRadius,
    ...finalContainerProps
  } = atoms.container;
  const borderRadiiStyles = (0, _react.useMemo)(() => ({
    borderRadius,
    borderBottomLeftRadius,
    borderBottomRightRadius,
    borderTopLeftRadius,
    borderTopRightRadius
  }), [borderRadius, borderBottomLeftRadius, borderBottomRightRadius, borderTopLeftRadius, borderTopRightRadius]);
  const onErrorHandler = error => {
    setError(true);
    if (onError) onError(error);
  };
  const loadRemoteImage = async (uri, options = {}) => {
    await new Promise(resolve => setTimeout(resolve, sourceDelay));
    if (shouldCache && _reactNative.Platform.OS !== "web") {
      try {
        const path = await _cacheManager.default.get(uri, options).getPath();
        if (isMounted.current) {
          if (path) {
            setUri(path);
          } else {
            onErrorHandler({
              nativeEvent: {
                error: new Error("Could not load image")
              }
            });
          }
        }
      } catch (error) {
        onErrorHandler({
          nativeEvent: {
            error
          }
        });
      }
    } else {
      setUri(uri);
    }
  };
  const renderFallback = (0, _react.useCallback)(() => {
    if (error) {
      if (!!fallbackComponent) {
        return /*#__PURE__*/_react.default.createElement(_box.default, _extends({
          overflow: "hidden"
        }, borderRadiiStyles, {
          style: {
            zIndex: 4
          }
        }), /*#__PURE__*/_react.default.cloneElement(fallbackComponent));
      }
      if (!!fallbackSource) {
        return /*#__PURE__*/_react.default.createElement(PearlRNImage, _extends({}, atoms.fallbackImage, borderRadiiStyles, {
          zIndex: 3,
          width: "100%",
          height: "100%",
          source: fallbackSource,
          style: _reactNative.StyleSheet.absoluteFill
        }));
      }
      return null;
    }
    return null;
  }, [error, fallbackComponent, fallbackSource, borderRadiiStyles]);
  const renderFinalImage = (0, _react.useCallback)(() => {
    if (isImageReady) {
      return /*#__PURE__*/_react.default.createElement(AnimatedView, {
        style: [_reactNative.StyleSheet.absoluteFill, {
          zIndex: 3,
          width: "100%",
          height: "100%",
          opacity: finalImageOpacity
        }]
      }, /*#__PURE__*/_react.default.createElement(PearlRNImage, _extends({}, restImageProps, borderRadiiStyles, {
        ref: ref,
        onError: onErrorHandler,
        testID: testID,
        source: finalSource,
        width: "100%",
        height: "100%"
      })));
    }
    return null;
  }, [ref, isImageReady, restImageProps, borderRadiiStyles, onErrorHandler, testID, finalSource]);
  const renderPreview = (0, _react.useCallback)(() => {
    if (!!previewSource) {
      return /*#__PURE__*/_react.default.createElement(AnimatedView, {
        style: {
          width: "100%",
          height: "100%",
          opacity: previewSourceOverlayOpacity
        }
      }, /*#__PURE__*/_react.default.createElement(PearlRNImage, _extends({}, atoms.previewImage, borderRadiiStyles, {
        source: previewSource,
        zIndex: 1,
        width: "100%",
        height: "100%",
        style: _reactNative.StyleSheet.absoluteFill,
        blurRadius: _reactNative.Platform.OS === "android" || _reactNative.Platform.OS === "web" ? 0.5 : 0
      })));
    }
  }, [previewSource, borderRadiiStyles]);
  const renderImageLoader = () => {
    if (typeof finalSource === "number") return null;
    if (loaderType === "progressive") {
      if (!!previewSource) {
        if (_reactNative.Platform.OS === "ios" && tint !== "none") {
          return /*#__PURE__*/_react.default.createElement(PearlAnimatedBlurView, _extends({
            tint: tint
          }, borderRadiiStyles, {
            zIndex: 3,
            overflow: "hidden",
            alignItems: "center",
            justifyContent: "center",
            intensity: blurIntensity,
            style: [_reactNative.StyleSheet.absoluteFill]
          }), renderFallback());
        } else {
          return /*#__PURE__*/_react.default.createElement(AnimatedView, {
            style: [_reactNative.StyleSheet.absoluteFill, {
              zIndex: 3,
              width: "100%",
              height: "100%",
              opacity: backwardCompatibleTintOverlayOpacity
            }]
          }, /*#__PURE__*/_react.default.createElement(_box.default, _extends({}, borderRadiiStyles, {
            w: "100%",
            h: "100%",
            overflow: "hidden",
            alignItems: "center",
            justifyContent: "center",
            bgColor: tint === "none" ? undefined : tint === "light" ? "white" : "black"
          }), renderFallback()));
        }
      }
      if (!!previewColor) {
        return /*#__PURE__*/_react.default.createElement(AnimatedView, {
          style: {
            zIndex: 3,
            width: "100%",
            height: "100%",
            opacity: previewColorOverlayOpacity
          }
        }, /*#__PURE__*/_react.default.createElement(_box.default, _extends({}, borderRadiiStyles, {
          w: "100%",
          h: "100%",
          overflow: "hidden",
          alignItems: "center",
          justifyContent: "center",
          bgColor: previewColor
        }), renderFallback()));
      }
    }
    if (loaderType === "spinner") {
      if (!error) return /*#__PURE__*/_react.default.createElement(_box.default, {
        width: "100%",
        height: "100%",
        style: _reactNative.StyleSheet.absoluteFill
      }, /*#__PURE__*/_react.default.createElement(_spinner.default, _extends({}, atoms.spinner, {
        isExpanded: true
      })));
      return renderFallback();
    }
  };
  (0, _react.useEffect)(() => {
    let reduceIntensity = false;
    if (isRemoteImage) {
      loadRemoteImage(source.uri, imageDownloadOptions);
      if (uri && !previousUri) reduceIntensity = true;
    } else reduceIntensity = true;
    if (reduceIntensity) _reactNative.Animated.timing(intensity, {
      toValue: 0,
      duration: overlayTransitionDuration,
      useNativeDriver: _reactNative.Platform.OS === "android"
    }).start();
    return () => {
      isMounted.current = false;
    };
  }, [uri, isRemoteImage, loadRemoteImage, source, imageDownloadOptions, overlayTransitionDuration]);
  return /*#__PURE__*/_react.default.createElement(_center.default, _extends({}, finalContainerProps, borderRadiiStyles, {
    accessible: true,
    accessibilityRole: "image"
  }), renderFinalImage(), renderPreview(), renderImageLoader());
}));

/** The Image component is used to display images. */
const Image = (0, _pearl.pearl)(CustomImage, {
  componentName: "Image",
  type: "molecule",
  animatable: true
}, undefined, {
  partForOverridenStyleProps: "container",
  partForOverridenNativeProps: "image",
  partForOverridenAnimationProps: "container"
});
Image.displayName = "Image";
var _default = exports.default = Image;
//# sourceMappingURL=image.js.map