import React, { useRef } from 'react';
import { Animated } from 'react-native';
import { SText } from '../../s-components/typography/s-text';
import { SBox } from '../../s-components/layout/s-box';
import { SBoxAnimated } from '../../s-components/layout/s-box-animated';

type TProps = {
  cards: { id: string; name: string }[];
};

const CARD_HEIGHT = 200;

// https://codedaily.io/tutorials/21/Pan-Responder-Inside-of-a-ScrollView
// https://www.programmersought.com/article/4969737328/
// https://github.com/facebook/react-native/issues/1046
// https://github.com/mjracca/react-native-scroll-block
// https://docs.swmansion.com/react-native-gesture-handler/docs/handler-pan
// https://github.com/rome2rio/react-native-touch-through-view
// https://blog.bitsrc.io/using-the-gesture-handler-in-react-native-c07f84ddfa49
// https://medium.com/@andi.gu.ca/react-native-3d-animations-2b2a14552feb
// https://github.com/facebook/react-native/releases/tag/v0.53.0
// https://stackoverflow.com/questions/38142552/scrollview-how-to-reproduce-snaptointerval-and-snaptoalignment-for-android#comment85464652_45666362
export const SnapCarousel: React.FC<TProps> = props => {
  const { cards } = props;
  const animation = useRef(new Animated.Value(0));

  const getComplexAnimations = (index: number) => {
    const inputRange = [
      (index - 1) * CARD_HEIGHT,
      (index - 1) * CARD_HEIGHT + CARD_HEIGHT / 2,
      index * CARD_HEIGHT,
      (index + 1) * CARD_HEIGHT - CARD_HEIGHT / 2,
      (index + 1) * CARD_HEIGHT,
    ];
    return [
      {
        opacity: animation.current.interpolate({
          inputRange,
          outputRange: [0, 0.9, 1, 0.5, 0],
          extrapolate: 'clamp',
        }),
      },
      {
        transform: [
          {
            scale: animation.current.interpolate({
              inputRange,
              outputRange: [0.8, 0.8, 1, 0.8, 0.8],
              extrapolate: 'clamp',
            }),
          },
          {
            translateY: animation.current.interpolate({
              inputRange,
              outputRange: [0, 0, 0, CARD_HEIGHT / 2, CARD_HEIGHT],
              extrapolate: 'clamp',
            }),
          },
          // hide behind
          // {
          //   translateY: animation.interpolate({
          //     inputRange,
          //     outputRange: [0, 0, 0, CARD_HEIGHT, CARD_HEIGHT * 2],
          //     extrapolate: 'clamp',
          //   }),
          // },
          // // 3d effect uncomment both props
          // { perspective: 500 },
          // {
          //   rotateX: animation.interpolate({
          //     inputRange,
          //     outputRange: ['-90deg', '0deg', '0deg', '0deg', '90deg'],
          //     extrapolate: 'clamp',
          //   }),
          // },
        ],
      },
    ];
  };

  const getComplexAnimationsDots = (index: number) => {
    const inputRange = [
      (index - 1) * CARD_HEIGHT,
      (index - 1) * CARD_HEIGHT + CARD_HEIGHT / 2,
      index * CARD_HEIGHT,
      (index + 1) * CARD_HEIGHT - CARD_HEIGHT / 2,
      (index + 1) * CARD_HEIGHT,
    ];
    return [
      {
        opacity: animation.current.interpolate({
          inputRange,
          outputRange: [0.2, 0.9, 1, 0.9, 0.2],
          extrapolate: 'clamp',
        }),
      },
      {
        transform: [
          {
            scale: animation.current.interpolate({
              inputRange,
              outputRange: [0.5, 0.5, 1, 0.5, 0.5],
              extrapolate: 'clamp',
            }),
          },
        ],
      },
    ];
  };

  return (
    <SBox flex={1}>
      <Animated.View style={{ flex: 1, backgroundColor: '#9798A7' }}>
        <SBox
          height={CARD_HEIGHT}
          overflow="hidden"
          border="1px solid blue"
          px={20}
          position="relative"
        >
          <Animated.ScrollView
            style={{ height: CARD_HEIGHT }}
            nestedScrollEnabled
            snapToAlignment="start"
            snapToInterval={CARD_HEIGHT}
            decelerationRate="normal"
            showsVerticalScrollIndicator={false}
            onScroll={Animated.event(
              [
                {
                  nativeEvent: {
                    contentOffset: { y: animation.current },
                  },
                },
              ],
              {
                useNativeDriver: true,
              }
            )}
          >
            {cards.map((card, i) => {
              return (
                <SBoxAnimated
                  key={card.id}
                  height={CARD_HEIGHT}
                  bg="comet"
                  style={[getComplexAnimations(i)]}
                >
                  <SText>{card.name}</SText>
                </SBoxAnimated>
              );
            })}
          </Animated.ScrollView>
          <SBox
            position="absolute"
            right={10}
            height="100%"
            border="1px solid white"
            justifyContent="center"
          >
            {cards.map((card, i) => {
              return (
                <SBoxAnimated
                  key={card.id}
                  bg="red"
                  style={[getComplexAnimationsDots(i)]}
                  my={5}
                >
                  <SBox width={10} height={10} />
                </SBoxAnimated>
              );
            })}
          </SBox>
        </SBox>
      </Animated.View>
    </SBox>
  );
};
