import React, { useState, useEffect, useRef } from 'react';
import { TouchableOpacity, Animated, useWindowDimensions, ScrollView, FlatList, View, TouchableHighlight } from 'react-native';
import { useSwipeable } from 'react-swipeable';
import { AtomIcon } from 'native/atoms/Icon';
import {
  SlideshowContainer,
  SlidesToShowContainer,
  SlideshowIndicators,
  Indicator,
  LeftArrowContainer,
  RightArrowContainer,
} from './styles';
import { keysTheme, theme } from 'data/dataMx';

export interface ISlideshowProps {
  /** object that receive properties for functionality in desktop, mobile and tablet */
  settings?: ISlideshowSettings;
  /** this is the total items inside the slideshow, for this is recommended to use items.lenght */
  totalItems: number;
  /** Componemt to render */
  children: React.ReactNode;
  /** Scroll arrows color */
  arrowColor?: keysTheme;
  /** Width of component to render. It will set to 100% if not present*/
  itemWidth?: string;
  /** Margin between rendered components */
  itemsMargin?: string;
}

interface ISlideshowSettings {
  mobile?: any;
}

export const OrganismSlideshow = ({
  settings = { mobile: {} },
  totalItems,
  children,
  arrowColor = 'neutral100',
  itemWidth = '100%',
  itemsMargin = '2%',
  ...props
}: ISlideshowProps) => {

  const [activeIndex, setActiveIndex] = useState<number>(0);
  const [autoplay, setAutoplay] = useState<boolean>(false);
  const [showDots, setshowDots] = useState<boolean>(false);
  const [showArrows, setshowArrows] = useState<boolean>(false);
  const [itemsToShow, setItemsToShow] = useState<number>(1);
  const [indicators, setIndicators] = useState<Array<number>>([]);
  const [slideshowDimension, setSlideshowDimension] = useState<any>({});
  const { mobile } = settings;
  let interval: any = null;
  const {width} = useWindowDimensions();

  const transitionAnimation = useRef(new Animated.Value(0)).current;
  const inputRange = [-1000, 0];
  const outputRange = [-10 * width, 0];


  /* istanbul ignore next */
  const updateIndex = (newIndex: number) => {
    let items = itemsToShow;
    if (itemsToShow > totalItems || itemsToShow === 0){
      items = totalItems;
    }
    if (newIndex === items || newIndex < 0){
      newIndex = 0;
    }
    if (itemWidth === '100%'){
      itemWidth = `${slideshowDimension.width}px`;
    }
    const marginPercentage = itemsMargin.includes('%',0) ?  parseInt(itemsMargin) : (parseInt(itemsMargin) / width) * 100;
    const widthPercentage = 100 * (parseInt(itemWidth) / width) + marginPercentage;
    Animated.timing(transitionAnimation, {
      toValue:  (-newIndex * widthPercentage) + marginPercentage,
      duration: 500,
      useNativeDriver: false,
    }).start();

    setActiveIndex(newIndex);
  };

  // for carousel settings
  useEffect(() => {
        /* istanbul ignore next */
      setAutoplay(mobile.autoplay || false);
        /* istanbul ignore next */

      setItemsToShow(mobile.itemsToShow || 1);
        /* istanbul ignore next */
      setshowDots(mobile.showDots || false);

      setshowArrows(mobile.showArrows || false);
  }, [width, itemsToShow]);

  // for autoplay
  useEffect(() => {
    if (autoplay) {
      /* istanbul ignore next */
      interval = setInterval(() => {
        
        updateIndex(activeIndex + 1);
      }, 4000);
  /* istanbul ignore next */
      return () => {
        if (interval) {
          clearInterval(interval);
        }
      };
    }
    return clearInterval(interval);
  }, [autoplay, updateIndex]);


  useEffect(() => {
    setIndicators(Array.from(Array(totalItems).keys()));
  }, [totalItems]);

  /* istanbul ignore next */
  const handlers = useSwipeable({
    onSwipedLeft: () => updateIndex(activeIndex + 1),
    onSwipedRight: () => updateIndex(activeIndex - 1),
  });

    /* istanbul ignore next */
  const handleTouchDots = (i: number) => {
    updateIndex(i);
  };

  const findDimensions = (layout: any)=>{
    setSlideshowDimension({
      ...layout
    })
  }

  return (
    <SlideshowContainer {...props} {...handlers} onLayout={(event: any)=>{findDimensions(event.nativeEvent.layout)}}>
      <SlidesToShowContainer>
        {showArrows && (
          <RightArrowContainer>
            <TouchableOpacity onPress={() => updateIndex(activeIndex + 1)}>
              <AtomIcon
                name={'keyboard_arrow_right'}
                size={20}
                color={arrowColor ?? 'neutral100'}
              />
            </TouchableOpacity>
          </RightArrowContainer>
        )}
        <Animated.View
          style={[
            {
              display: 'flex',
              flexDirection: 'row',
              transform: [
                {
                  translateX: transitionAnimation.interpolate({
                    inputRange,
                    outputRange,
                  }),
                },
              ],
            },
          ]}
        >
            {children}
        </Animated.View>
        {showArrows && (
          <LeftArrowContainer>
            <TouchableOpacity onPress={() => updateIndex(activeIndex - 1) }>
              <AtomIcon
                name={'keyboard_arrow_left'}
                size={20}
                color={arrowColor ?? 'neutral100'}
              />
            </TouchableOpacity>
          </LeftArrowContainer>
        )}
      </SlidesToShowContainer>
      {showDots &&
         (
         <SlideshowIndicators width={'100%'}>
           {indicators
            .map((_item: any, i: number) => (
              <TouchableOpacity
                onPress={() => {
                  handleTouchDots(i);
                }}
                key={i}
              >
                <Indicator
                  activeItem={activeIndex === i ? theme.primary : 'transparent'}
                />
              </TouchableOpacity>
            ))}
         </SlideshowIndicators>
       )
      }
    </SlideshowContainer>
  );
};
