import React, { useCallback, useRef } from 'react';
import { ScrollView, Dimensions, LayoutChangeEvent } from 'react-native';
import { SBox } from '../s-components/layout/s-box';

const { width: DEVICE_WIDTH } = Dimensions.get('window');

type TProps = {
  testID: string;
  renderItem: (item: any, i?: number, callback?: Function) => React.ReactNode;
  keyId: string | number;
  outerGap?: number;
  innerGap?: number;
  data: any[];
};

export const MagneticCarousel = (props: TProps) => {
  const { data, renderItem, keyId, outerGap, innerGap, testID } = props;
  const carouselRef = useRef(null);
  const slidesCoordinates = useRef(new Array(data.length));
  const slidesWidth = useRef(new Array(data.length));

  const scrollHandler = useCallback((key: number) => {
    const coordArr = slidesCoordinates.current;
    const widthdArr = slidesWidth.current;
    const curRef = carouselRef.current;
    if (carouselRef && curRef) {
      if (key === 0) {
        // @ts-ignore
        curRef.scrollTo({
          x: 0,
          y: 0,
          animated: true,
        });
      } else if (coordArr.length - 1 === key) {
        // @ts-ignore
        curRef.scrollToEnd();
      } else {
        // @ts-ignore
        curRef.scrollTo({
          x: coordArr[key] - DEVICE_WIDTH / 2 + widthdArr[key] / 2,
          y: 0,
          animated: true,
        });
      }
    }
  }, []);

  const renderItemView = useCallback(
    (item: any, key: number) => {
      return (
        <SBox
          pl={innerGap}
          key={item[keyId]}
          onLayout={(event: LayoutChangeEvent) => {
            const { layout } = event.nativeEvent;
            slidesCoordinates.current[key] = layout.x;
            slidesWidth.current[key] = layout.width;
          }}
        >
          {renderItem(item, key, () => {
            scrollHandler(key);
          })}
        </SBox>
      );
    },
    [renderItem]
  );

  return (
    <SBox>
      <ScrollView
        testID={testID}
        contentContainerStyle={{
          paddingLeft: outerGap! - innerGap!,
          paddingRight: outerGap,
        }}
        ref={ref => {
          // @ts-ignore
          carouselRef.current = ref;
        }}
        scrollEnabled
        horizontal
        showsHorizontalScrollIndicator={false}
        scrollEventThrottle={16}
      >
        {data.map(renderItemView)}
      </ScrollView>
    </SBox>
  );
};

MagneticCarousel.defaultProps = {
  outerGap: 0,
  innerGap: 0,
};
