import React, { useEffect, useMemo, useRef } from 'react';
import type { ViewProps } from 'react-native';
import { Animated, Platform, Pressable } from 'react-native';
import Icon from '../Icon';
import { StyledIconWrapper, StyledWrapper } from './StyledRate';

interface RateOption<T extends string | number> {
  value: T;
}

interface RateProps<T extends string | number> extends ViewProps {
  /**
   * Options for rate component.
   */
  options: RateOption<T>[];
  /**
   * Value of the component.
   */
  value?: T;
  /**
   * Callback when value changes.
   */
  onChange?: (value: T) => void;
  /**
   * Whether the component is readonly.
   */
  readonly?: boolean;
  /**
   * Whether the component is disabled.
   */
  disabled?: boolean;
}

const Rate = <T extends string | number>({
  options,
  value,
  onChange,
  readonly = false,
  disabled = false,
  ...otherProps
}: RateProps<T>) => {
  const valueIndex = useMemo(
    () => options.findIndex((item) => item.value === value),
    [value, options]
  );

  const animatedValue = useRef(new Animated.Value(0)).current;

  const scale = animatedValue.interpolate({
    inputRange: [0, 1],
    outputRange: [0.8, 1],
  });

  useEffect(() => {
    animatedValue.setValue(0);

    Animated.spring(animatedValue, {
      toValue: 1,
      useNativeDriver: Platform.OS !== 'web',
    }).start();
  }, [value, animatedValue]);

  return (
    <StyledWrapper {...otherProps}>
      {options.length > 0 &&
        options.map((item, index) => (
          <Pressable
            key={item.value}
            disabled={disabled || readonly}
            onPress={() => onChange?.(item.value)}
            testID={item.value.toString()}
          >
            <StyledIconWrapper
              style={
                valueIndex === index && {
                  transform: [{ scale }],
                }
              }
            >
              <Icon
                icon={index <= valueIndex ? 'star' : 'star-outlined'}
                intent={disabled ? 'disabled-text' : 'primary'}
              />
            </StyledIconWrapper>
          </Pressable>
        ))}
    </StyledWrapper>
  );
};

export default Rate;
