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); }
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { Video as ExpoVideo } from "expo-av";
import { pearl } from "../../../pearl";
import { Animated, Platform, Image as RNImage } from "react-native";
import { View, StyleSheet } from "react-native";
import { BlurView } from "expo-blur";
import Box from "../../atoms/box/box";
import Spinner from "../../atoms/spinner/spinner";
import Center from "../../atoms/center/center";
const PearlRNImage = pearl(RNImage, {
  componentName: "",
  type: "basic",
  animatable: true
});
const PearlExpoVideo = pearl(ExpoVideo, {
  componentName: "Video",
  type: "basic",
  animatable: true
});
const AnimatedView = Animated.createAnimatedComponent(View);
const AnimatedBlurView = Animated.createAnimatedComponent(BlurView);
const PearlAnimatedBlurView = pearl(AnimatedBlurView, {
  componentName: "",
  type: "basic",
  animatable: true
});
const PearlAnimatedView = pearl(AnimatedView, {
  componentName: "",
  type: "basic",
  animatable: true
});
const BaseVideo = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef(({
  atoms
}, ref) => {
  const {
    source,
    onError,
    testID,
    previewSource,
    fallbackSource,
    fallbackComponent,
    previewColor,
    tint = "dark",
    loaderType = "spinner",
    sourceDelay = 0,
    overlayTransitionDuration = 300,
    onLoad,
    onLoadStart,
    ...restVideoProps
  } = atoms.video;
  const isRemoteVideo = typeof source === "object";
  const [error, setError] = useState(false);
  const [hasVideoLoaded, setHasVideoLoaded] = useState(false);
  const intensity = useRef(new 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]
  });

  // Separate out border radius properties
  const {
    borderRadius,
    borderBottomLeftRadius,
    borderBottomRightRadius,
    borderTopLeftRadius,
    borderTopRightRadius,
    ...finalContainerProps
  } = atoms.container;
  const borderRadiiStyles = useMemo(() => ({
    borderRadius,
    borderBottomLeftRadius,
    borderBottomRightRadius,
    borderTopLeftRadius,
    borderTopRightRadius
  }), [borderRadius, borderBottomLeftRadius, borderBottomRightRadius, borderTopLeftRadius, borderTopRightRadius]);

  // A handler function for catching errors while loading the video
  const onErrorHandler = error => {
    setError(true);
    if (onError) onError(error);
  };
  const renderFallback = useCallback(() => {
    if (error) {
      if (!!fallbackComponent) {
        return /*#__PURE__*/React.createElement(Box, _extends({
          overflow: "hidden"
        }, borderRadiiStyles, {
          style: {
            zIndex: 4
          }
        }), /*#__PURE__*/React.cloneElement(fallbackComponent));
      }
      if (!!fallbackSource) {
        return /*#__PURE__*/React.createElement(PearlRNImage, _extends({}, atoms.fallbackImage, borderRadiiStyles, {
          zIndex: 3,
          width: "100%",
          height: "100%",
          source: fallbackSource,
          style: StyleSheet.absoluteFill
        }));
      }
    }
    return null;
  }, [error, fallbackComponent, fallbackSource, borderRadiiStyles, atoms.fallbackImage]);
  const renderVideo = useCallback(() => {
    return /*#__PURE__*/React.createElement(AnimatedView, {
      style: [StyleSheet.absoluteFill, {
        zIndex: 3,
        width: "100%",
        height: "100%",
        opacity: finalImageOpacity
      }]
    }, /*#__PURE__*/React.createElement(PearlExpoVideo, _extends({}, restVideoProps, borderRadiiStyles, {
      ref: ref,
      visible: hasVideoLoaded,
      onLoad: async status => {
        await new Promise(resolve => setTimeout(resolve, sourceDelay));
        if (onLoad) onLoad(status);
        if (status.isLoaded) Animated.timing(intensity, {
          toValue: 0,
          duration: overlayTransitionDuration,
          useNativeDriver: Platform.OS === "android"
        }).start();
        setHasVideoLoaded(true);
      },
      onLoadStart: () => {
        if (Platform.OS === "ios") {
          setTimeout(() => {
            if (!hasVideoLoaded) {
              setError(true);
            }
          }, 1000);
        }
        if (onLoadStart) onLoadStart();
      },
      onError: onErrorHandler,
      testID: testID,
      source: source,
      width: "100%",
      height: "100%"
    })));
  }, [restVideoProps, borderRadiiStyles, ref, hasVideoLoaded, onLoad, isRemoteVideo, intensity, overlayTransitionDuration, onLoadStart, onErrorHandler, testID, source]);
  const renderPreview = useCallback(() => {
    if (intensity._value === 0) return null;
    if (!!previewSource) {
      return /*#__PURE__*/React.createElement(AnimatedView, {
        style: {
          width: "100%",
          height: "100%",
          opacity: previewSourceOverlayOpacity
        }
      }, /*#__PURE__*/React.createElement(PearlRNImage, _extends({}, atoms.previewImage, borderRadiiStyles, {
        source: previewSource,
        zIndex: 1,
        width: "100%",
        height: "100%",
        style: StyleSheet.absoluteFill,
        blurRadius: Platform.OS === "android" || Platform.OS === "web" ? 0.5 : 0
      })));
    }
  }, [intensity, previewSource, borderRadiiStyles, atoms.previewImage]);
  const renderImageLoader = useCallback(() => {
    if (intensity._value === 0) return null;
    if (loaderType === "progressive") {
      if (!!previewSource) {
        if (Platform.OS === "ios" && tint !== "none") {
          return /*#__PURE__*/React.createElement(PearlAnimatedBlurView, _extends({
            tint: tint
          }, borderRadiiStyles, {
            zIndex: 3,
            overflow: "hidden",
            alignItems: "center",
            justifyContent: "center",
            intensity: blurIntensity,
            style: [StyleSheet.absoluteFill]
          }), renderFallback());
        } else {
          return /*#__PURE__*/React.createElement(AnimatedView, {
            style: [StyleSheet.absoluteFill, {
              zIndex: 3,
              width: "100%",
              height: "100%",
              opacity: backwardCompatibleTintOverlayOpacity
            }]
          }, /*#__PURE__*/React.createElement(Box, _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.createElement(AnimatedView, {
          style: {
            zIndex: 3,
            width: "100%",
            height: "100%",
            opacity: previewColorOverlayOpacity
          }
        }, /*#__PURE__*/React.createElement(Box, _extends({}, borderRadiiStyles, {
          w: "100%",
          h: "100%",
          overflow: "hidden",
          alignItems: "center",
          justifyContent: "center",
          bgColor: previewColor
        }), renderFallback()));
      }
    }
    if (loaderType === "spinner") {
      if (!error) return /*#__PURE__*/React.createElement(Box, {
        width: "100%",
        height: "100%",
        style: StyleSheet.absoluteFill
      }, /*#__PURE__*/React.createElement(Spinner, _extends({}, atoms.spinner, {
        isExpanded: true
      })));
      return renderFallback();
    }
  }, [intensity, loaderType, previewSource, borderRadiiStyles, tint, blurIntensity, previewSourceOverlayOpacity, renderFallback, previewColor, previewColorOverlayOpacity, error, atoms.spinner]);
  useEffect(() => {
    setHasVideoLoaded(false);
    intensity.setValue(100);
  }, [JSON.stringify(source)]);
  return /*#__PURE__*/React.createElement(Center, _extends({}, finalContainerProps, borderRadiiStyles, {
    accessible: true,
    accessibilityRole: "image"
  }), renderVideo(), renderPreview(), renderImageLoader());
}));

/**
 * Video is the most abstract component on top of which all other Pearl UI components are built.
 */
const Video = pearl(BaseVideo, {
  componentName: "Video",
  type: "molecule",
  animatable: true
}, undefined, {
  partForOverridenStyleProps: "container",
  partForOverridenNativeProps: "video",
  partForOverridenAnimationProps: "container"
});
Video.displayName = "Video";
export default Video;
//# sourceMappingURL=video.js.map