import {memo} from 'react';
import Reanimated, {
  Extrapolation,
  interpolate,
  SharedValue,
  useAnimatedStyle,
} from 'react-native-reanimated';

import {styles} from './styles';

interface Props {
  indexDecimal: SharedValue<number>;
  inputRange: number[];
  translateXOutputRange: number[];
  scaleXOutputRange: number[];
  baseWidth: number;
  enableAnimation: boolean;
  totalTabs: number;
  /** Must equal `totalTabs` once every tab has been laid out. */
  tabDimensionsLength: number;
  pillBackgroundColor: string;
  lineColor: string;
}

/**
 * Tab indicators animated with Reanimated on the UI thread.
 * Used when `indexDecimal` is provided (e.g. react-native-collapsible-tab-view)
 * to avoid bridging to RN `Animated` via `runOnJS` every frame.
 */
function TabsHeaderReanimatedIndicators({
  indexDecimal,
  inputRange,
  translateXOutputRange,
  scaleXOutputRange,
  baseWidth,
  enableAnimation,
  totalTabs,
  tabDimensionsLength,
  pillBackgroundColor,
  lineColor,
}: Props) {
  const animatedStyle = useAnimatedStyle(() => {
    if (!enableAnimation || tabDimensionsLength !== totalTabs) {
      return {};
    }

    if (totalTabs === 1) {
      if (translateXOutputRange.length < 1 || scaleXOutputRange.length < 1) {
        return {};
      }

      return {
        width: baseWidth,
        transform: [
          {translateX: translateXOutputRange[0]},
          {scaleX: scaleXOutputRange[0]},
        ],
      };
    }

    if (
      inputRange.length === 0 ||
      translateXOutputRange.length === 0 ||
      inputRange.length !== translateXOutputRange.length
    ) {
      return {};
    }

    const tx = interpolate(
      indexDecimal.value,
      inputRange,
      translateXOutputRange,
      Extrapolation.CLAMP,
    );
    const sx = interpolate(
      indexDecimal.value,
      inputRange,
      scaleXOutputRange,
      Extrapolation.CLAMP,
    );

    return {
      width: baseWidth,
      transform: [{translateX: tx}, {scaleX: sx}],
    };
  }, [
    enableAnimation,
    totalTabs,
    tabDimensionsLength,
    baseWidth,
    inputRange,
    translateXOutputRange,
    scaleXOutputRange,
    indexDecimal,
  ]);

  return (
    <>
      <Reanimated.View
        style={[
          styles.selectedTabIndicator,
          {backgroundColor: pillBackgroundColor},
          animatedStyle,
        ]}
      />
      <Reanimated.View
        style={[
          styles.lineIndicator,
          {backgroundColor: lineColor},
          animatedStyle,
        ]}
      />
    </>
  );
}

export default memo(TabsHeaderReanimatedIndicators);
