"use strict";

/* eslint-disable functional/immutable-data */
import { forwardRef, useCallback, useImperativeHandle, useRef, useState } from "react";
import { Dimensions, Platform, Pressable, StyleSheet, TextInput, View } from "react-native";
import Animated, { Easing, Extrapolation, interpolate, interpolateColor, useAnimatedStyle, useSharedValue, withTiming } from "react-native-reanimated";
import { useIONewTypeface, useIOTheme } from "../../context";
import { IOColors, IOVisualCostants } from "../../core";
import { IOMaxFontSizeMultiplier, makeFontStyleObject } from "../../utils/fonts";
import { Icon } from "../icons";
import { buttonTextFontSize, buttonTextLineHeight, IOText } from "../typography";

/* Component visual attributes */
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const inputPaddingHorizontal = 12;
const inputPaddingVertical = 8;
const inputPaddingClearButton = 8;
const inputRadius = 8;
const iconMargin = 8;
const iconSize = 16;
const iconCloseSize = 24;
const inputFontSizePlaceholder = 14;
const cancelButtonMargin = 16;
const inputTransitionDuration = 250;
const AnimatedTextInput = Animated.createAnimatedComponent(TextInput);
const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
const inputWithTimingConfig = {
  duration: inputTransitionDuration,
  easing: Easing.inOut(Easing.cubic)
};
export const SearchInput = /*#__PURE__*/forwardRef(({
  accessibilityLabel,
  cancelButtonLabel,
  clearAccessibilityLabel,
  placeholder,
  autoFocus,
  keepCancelVisible = false,
  onCancel,
  onChangeText,
  pressable,
  testID,
  value = ""
}, ref) => {
  const searchInputRef = useRef(null);
  const {
    newTypefaceEnabled
  } = useIONewTypeface();

  /* Component visual attributes */
  const theme = useIOTheme();
  const inputCaretColor = IOColors[theme["interactiveElem-default"]];
  const inputBgColorDefault = IOColors[theme["appBackground-secondary"]];
  const inputBgColorFocused = IOColors[theme["appBackground-tertiary"]];
  const inputColorPlaceholder = IOColors[theme["textBody-tertiary"]];
  const iconColor = theme["textBody-tertiary"];

  /* Widths used for the transition:
     - `SearchInput` entire width
     - `Cancel` button */
  const inputWidth = Dimensions.get("window").width - IOVisualCostants.appMarginDefault * 2;
  const [cancelButtonWidth, setCancelButtonWidth] = useState(0);
  const getCancelButtonWidth = ({
    nativeEvent
  }) => {
    setCancelButtonWidth(nativeEvent.layout.width);
  };
  const inputWidthWithCancel = inputWidth - cancelButtonWidth;
  useImperativeHandle(ref, () => ({
    focus() {
      searchInputRef.current?.focus();
    }
  }), []);

  /* Reanimated styles */
  const inputAnimatedWidth = useSharedValue(inputWidth);
  const isFocused = useSharedValue(0);

  /* Applied to the `SearchInput` */
  const animatedStyle = useAnimatedStyle(() => ({
    width: withTiming(inputAnimatedWidth.value, inputWithTimingConfig),
    backgroundColor: interpolateColor(isFocused.value, [0, 1], [inputBgColorDefault, inputBgColorFocused])
  }));

  /* Applied to the `Cancel` button */
  const cancelButtonAnimatedStyle = useAnimatedStyle(() => {
    const showCancelButton = !pressable && keepCancelVisible ? 1 : isFocused.value;
    return {
      transform: [{
        translateX: interpolate(showCancelButton, [0, 1], [cancelButtonWidth + IOVisualCostants.appMarginDefault, 0], Extrapolation.CLAMP)
      }],
      opacity: interpolate(showCancelButton, [0, 1], [0.5, 1])
    };
  });

  /* Applied to the `Clear` button inside the `SearchInput` */
  const clearButtonAnimatedStyle = useAnimatedStyle(() => {
    const showClearButton = value.length > 0;
    return {
      transform: [{
        scale: showClearButton ? withTiming(1, inputWithTimingConfig) : withTiming(0.5, inputWithTimingConfig)
      }],
      opacity: withTiming(showClearButton ? 1 : 0, inputWithTimingConfig)
    };
  }, [value]);

  /* Related event handlers */
  const handleFocus = () => {
    isFocused.value = withTiming(1, inputWithTimingConfig);
    inputAnimatedWidth.value = inputWidthWithCancel;
  };
  const handleBlur = () => {
    isFocused.value = withTiming(0, inputWithTimingConfig);
    inputAnimatedWidth.value = keepCancelVisible ? inputWidthWithCancel : inputWidth;
  };
  const handleCancel = useCallback(event => {
    onChangeText?.("");
    onCancel?.(event);
  }, [onCancel, onChangeText]);
  const handleClear = useCallback(() => {
    onChangeText?.("");
    searchInputRef.current?.clear();
  }, [onChangeText]);
  const handleChangeText = useCallback(text => onChangeText?.(text), [onChangeText]);
  const renderSearchBar = () => /*#__PURE__*/_jsxs(Animated.View, {
    importantForAccessibility: pressable ? "no-hide-descendants" : "auto",
    style: styles.searchBar,
    children: [/*#__PURE__*/_jsxs(Animated.View, {
      style: [styles.searchInput, animatedStyle],
      pointerEvents: pressable ? "none" : "auto",
      children: [/*#__PURE__*/_jsx(View, {
        style: styles.iconContainer,
        children: /*#__PURE__*/_jsx(Icon, {
          allowFontScaling: true,
          name: "search",
          size: iconSize,
          color: iconColor
        })
      }), /*#__PURE__*/_jsx(AnimatedTextInput, {
        testID: testID,
        ref: searchInputRef,
        inputMode: "search",
        returnKeyType: "search",
        accessibilityRole: "search",
        accessibilityLabel: accessibilityLabel,
        numberOfLines: 1,
        style: [{
          color: IOColors[theme["textBody-default"]],
          ...makeFontStyleObject(inputFontSizePlaceholder, newTypefaceEnabled ? "Titillio" : "TitilliumSansPro", undefined, "Regular")
        }, styles.textInput, Platform.OS === "ios" ? styles.textInputIOS : styles.textInputAndroid],
        selectionColor: inputCaretColor,
        cursorColor: inputCaretColor,
        placeholder: placeholder,
        placeholderTextColor: inputColorPlaceholder,
        onFocus: handleFocus,
        onBlur: handleBlur,
        onChangeText: handleChangeText,
        value: value,
        autoFocus: autoFocus,
        maxFontSizeMultiplier: IOMaxFontSizeMultiplier
      }), /*#__PURE__*/_jsx(AnimatedPressable, {
        style: [styles.clearButton, clearButtonAnimatedStyle],
        onPress: handleClear,
        accessibilityLabel: clearAccessibilityLabel,
        accessibilityRole: "button",
        hitSlop: 16,
        children: /*#__PURE__*/_jsx(Icon, {
          name: "closeSmall",
          size: iconCloseSize,
          color: iconColor
        })
      })]
    }), /*#__PURE__*/_jsx(Animated.View, {
      onLayout: getCancelButtonWidth,
      style: [styles.cancelButton, cancelButtonAnimatedStyle],
      children: /*#__PURE__*/_jsx(Pressable, {
        accessibilityRole: "button",
        accessibilityLabel: cancelButtonLabel,
        onPress: handleCancel,
        children: /*#__PURE__*/_jsx(IOText, {
          color: theme["interactiveElem-default"],
          weight: "Semibold",
          size: buttonTextFontSize,
          lineHeight: buttonTextLineHeight,
          numberOfLines: 1,
          accessible: false,
          accessibilityElementsHidden: true,
          importantForAccessibility: "no-hide-descendants",
          children: cancelButtonLabel
        })
      })
    })]
  });
  return pressable ? /*#__PURE__*/_jsx(Pressable, {
    accessible: true,
    accessibilityRole: "button",
    accessibilityLabel: placeholder,
    onPress: pressable.onPress,
    children: renderSearchBar()
  }) : renderSearchBar();
});
const styles = StyleSheet.create({
  searchBar: {
    width: "100%",
    flexDirection: "row",
    justifyContent: "flex-start",
    alignItems: "center"
  },
  searchInput: {
    flexShrink: 0,
    borderRadius: inputRadius,
    borderCurve: "continuous",
    flexDirection: "row",
    alignItems: "center",
    paddingLeft: inputPaddingHorizontal,
    paddingRight: inputPaddingClearButton
  },
  textInput: {
    flexShrink: 1,
    flexGrow: 1
  },
  textInputIOS: {
    paddingVertical: inputPaddingVertical
  },
  textInputAndroid: {
    textAlignVertical: "center",
    overflow: "hidden"
  },
  iconContainer: {
    marginRight: iconMargin
  },
  cancelButton: {
    position: "absolute",
    right: 0,
    paddingLeft: cancelButtonMargin
  },
  clearButton: {
    transformOrigin: "center",
    marginLeft: iconMargin
  }
});
//# sourceMappingURL=SearchInput.js.map