import React, { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
import { Animated, Dimensions, LayoutRectangle, ScrollView, View } from 'react-native';
import * as _ from 'lodash';
import { useTheme } from 'styled-components';
import { useDidUpdateEffect } from '../../../hooks/useDidUpdateEffect';
import { ITheme } from '../../AppProvider/ITheme';
import { RSValue } from '../../RFValue';
import { IPropsTabs, ITabsRef } from '../Tabs.interface';
import { Container, TabActive, TabContainer, Tab as TabDefault } from './Tabs.style';

export const Tabs = React.forwardRef(function Tabs(
   { options, onSelect, disabled = false, skeleton = false, defaultTab }: IPropsTabs,
   ref: any,
) {
   const theme: ITheme = useTheme();
   // Tab selecionada (index)
   const indexDefault = useMemo(() => options.findIndex((i) => i.id === defaultTab), [options]);
   const [selectTabIndex, setSelectTabIndex] = useState<number>(indexDefault === -1 ? 0 : indexDefault);
   // Ref do container de tabs
   const scrollViewRef = useRef<any>();
   const layoutTabsRef = useRef<{ [key: string]: LayoutRectangle }>({});
   //
   const animatedwidth = useRef(new Animated.Value(-8000)).current;
   const animatedTrans = useRef(new Animated.Value(0)).current;

   /**
    * Selecionar tab
    */
   const setTab = useCallback(function setTab(item, indexTab, runCallback = true): void {
      setSelectTabIndex((currentSelect) => {
         if (currentSelect !== indexTab) {
            if (runCallback) {
               onSelect(options[indexTab]);
            }

            return indexTab;
         }

         return currentSelect;
      });
   }, []);

   const onPressTab = useCallback((tab: any, index: number, layoutRef: any, runCallback = true): void => {
      if (layoutRef) {
         Animated.timing(animatedwidth, {
            toValue: layoutRef.width - 8000,
            duration: 200,
            useNativeDriver: true,
         }).start();

         Animated.timing(animatedTrans, {
            toValue: layoutRef.x,
            duration: 200,
            useNativeDriver: true,
         }).start();

         const scrollX = layoutRef.x - Dimensions.get('window').width / 2 + layoutRef.width / 2;

         // Apenas se scroll for maior que a tela
         // if (layoutRef.width > Dimensions.get('window').width) {
         scrollViewRef?.current?.getScrollResponder()?.scrollTo({ x: scrollX, y: 0, animated: true });
         // }
      }

      setTab(tab, index, runCallback);
   }, []);

   useImperativeHandle(
      ref,
      () => ({
         setTab: (tab) => {
            const indexTab = options.findIndex((i) => i.id === tab);

            if (indexTab !== -1) {
               onPressTab(options[indexTab], indexTab, layoutTabsRef.current[indexTab], false);
            }
         },
      }),
      [],
   );

   return (
      <Container>
         <ScrollView ref={scrollViewRef} horizontal showsHorizontalScrollIndicator={false}>
            <Animated.View
               style={{
                  marginVertical: RSValue(10),
                  transform: [
                     {
                        translateX: animatedTrans,
                     },
                  ],
                  zIndex: 1,
                  position: 'absolute',
                  overflow: 'hidden',
                  borderRadius: RSValue(20),
               }}
            >
               <Animated.View
                  style={{
                     transform: [
                        {
                           translateX: animatedwidth,
                        },
                     ],
                     borderRadius: RSValue(20),
                     backgroundColor: theme?.tabs?.backgroundActiveColor ?? 'black',
                     width: 8000,
                     height: RSValue(30),
                  }}
               />
            </Animated.View>

            <View style={{ flexDirection: 'row', zIndex: 10, paddingHorizontal: RSValue(10) }}>
               {options &&
                  options.map((item, i) => (
                     <Tab
                        tabRef={layoutTabsRef}
                        key={i}
                        index={i}
                        item={item}
                        onPressTab={onPressTab}
                        selected={i === selectTabIndex}
                        skeleton={skeleton}
                     />
                  ))}
            </View>
         </ScrollView>
      </Container>
   );
});

const Tab = React.memo<any>(function Tab({ index, item, selected, onPressTab, skeleton, tabRef }): JSX.Element {
   const layoutRef = useRef({});

   return (
      <TabContainer
         onLayout={(ev) => {
            layoutRef.current = ev.nativeEvent.layout;
            tabRef.current[index] = ev.nativeEvent.layout;

            if (selected) {
               onPressTab(item, index, layoutRef.current, false);
            }
         }}
         key={`tab-${index}`}
         testID={`tab-${index}`}
         selected={selected}
         onPress={() => !skeleton && onPressTab(item, index, layoutRef.current)}
      >
         {!selected && <TabDefault skeleton={skeleton}>{item.name}</TabDefault>}
         {selected && <TabActive skeleton={skeleton}>{item.name}</TabActive>}
      </TabContainer>
   );
});
