/* eslint-disable @typescript-eslint/no-explicit-any */
import React, {memo, useMemo} from 'react';
import isEqual from 'react-fast-compare';
import Animated, {useAnimatedStyle} from 'react-native-reanimated';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import {useInterpolate} from '../../AnimatedHelper';
import type {DotProps} from '../../types';
import {HEIGHT_HOLE} from '../constant';
import {IconDot} from './IconDot';
import {styles} from './style';

const DotComponent = (props: DotProps) => {
  // props
  const {
    selectedIndex,
    routes,
    progress,
    width,
    dotColor,
    dotSize,
    barHeight,
    isRtl,
    navigationIndex,
  } = props;

  // const
  const {bottom} = useSafeAreaInsets();
  const inputRange = useMemo(
    () => routes.map((_: any, index: number) => index),
    [routes],
  );
  const outputRange = useMemo(
    () =>
      isRtl
        ? routes.map(
            (_: any, index: number) =>
              -(
                (index * width) / routes.length +
                width / routes.length / 2 -
                dotSize / 2
              ),
          )
        : routes.map(
            (_: any, index: number) =>
              (index * width) / routes.length +
              width / routes.length / 2 -
              dotSize / 2,
          ),
    [isRtl, routes, width, dotSize],
  );

  // reanimated
  const translateX = useInterpolate(selectedIndex, inputRange, outputRange);
  const translateY = useInterpolate(
    progress,
    [0, 1],
    [15 - bottom, -(barHeight - HEIGHT_HOLE + 5)],
  );

  const opacity = useInterpolate(progress, [0, 1], [0.2, 1]);

  // reanimated style
  const iconContainerStyle = useAnimatedStyle(() => ({
    opacity: opacity.value,
    justifyContent: 'center',
    alignItems: 'center',
  }));

  const dotStyle = useAnimatedStyle(() => ({
    width: dotSize,
    backgroundColor: dotColor,
    height: dotSize,
    bottom: 0,
    borderRadius: dotSize / 2,
    transform: [{translateX: translateX.value}, {translateY: translateY.value}],
  }));

  // render
  return (
    <Animated.View style={[styles.dot, dotStyle]}>
      <Animated.View style={iconContainerStyle}>
        {routes.map(({icon}, index: number) => (
          <IconDot key={index} index={index} selectedIndex={selectedIndex}>
            {icon({progress, focused: navigationIndex === index})}
          </IconDot>
        ))}
      </Animated.View>
    </Animated.View>
  );
};

export const Dot = memo(DotComponent, isEqual);