import React, { useState, useRef, useEffect, useCallback } from "react";
import { Animated, Easing } from "react-native";

type FocusDirection = {
  value: "up" | "down" | "right" | "left";
};

const animate = (animatedValue, toValue, animatedOptions) => {
  const animationConfig = {
    toValue,
    duration: 300,
    easing: Easing.in(Easing.bezier(0.25, 0.1, 0.25, 1.0)),
    useNativeDriver: true,
  };

  Animated.timing(
    animatedValue,
    Object.assign({}, animationConfig, animatedOptions)
  ).start();
};

export function useFadeOutWhenBlurred(
  component: ZappUIComponent<any, { fade_out_when_blurred: boolean }>,
  animatedOptions = {}
) {
  const [visible, setVisible] = useState(true);
  const opacity = useRef(new Animated.Value(1)).current;

  const willReceiveFocus = useCallback(() => {
    setVisible((visible) => (!visible ? true : visible));
  }, []);

  const hasLostFocus = useCallback((_, direction: FocusDirection) => {
    setVisible((visible) =>
      visible && direction?.value === "down" ? false : visible
    );
  }, []);

  useEffect(() => {
    if (component.rules.fade_out_when_blurred) {
      animate(opacity, visible ? 1 : 0, animatedOptions);
    }
  }, [visible]);

  return React.useMemo(
    () => ({
      opacity,
      willReceiveFocus,
      hasLostFocus,
    }),
    [willReceiveFocus, hasLostFocus]
  );
}
