import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef } from 'react';
import { View, Animated, ScrollView } from 'react-native';
import { LoaderIcon } from '../../../LoaderIcon/native';
import { PageErrorLoad } from '../../../PageListingError/native';
import { PageListingErrorLoadMore } from '../../../PageListingErrorLoadMore/native';
import { PageListingNotFound } from '../../../PageListingNotFound/native';
import { Pagination } from '../../../Pagination';
import { RSValue } from '../../../RFValue';
import { IPageListingChildrenProps } from '../PageListing.interface';
import { CardsListingContainerStyle } from './CardsListingContainer.style';

export function CardsListingContainer(props: IPageListingChildrenProps): JSX.Element {
   const { renderResourceSkeleton, viewList, paddingScroll, navActions, navActionsSize } = props;
   const { skeletonResources, setPage, starting, searching, resources, reloadPage, errorLoadData } = viewList;

   const contentContainerStyle = useMemo(
      () => ({
         paddingTop: navActions?.selected ? navActionsSize : 2 * paddingScroll,
         paddingBottom: navActions?.selected ? 2 * paddingScroll + navActionsSize : paddingScroll + navActionsSize,
      }),
      [paddingScroll, navActions?.selected],
   );

   const showCardsSkeleton = starting || searching;
   const showPageError = errorLoadData;
   const showCards = !starting && !searching && resources && !showPageError;

   const keyExtractorSkeleton = useCallback((item: any, index: number) => `card-skeleton-${index}`, []);
   const renderItemFlatListSkeleton = useCallback(
      (item) => <View testID="skeleton-card">{renderResourceSkeleton(item.item, item.index)}</View>,
      [renderResourceSkeleton],
   );

   return (
      <View style={{ flex: 1 }}>
         {showPageError && (
            <View
               style={{
                  flex: 1,
                  justifyContent: 'center',
                  alignItems: 'center',
                  flexGrow: 1,
                  paddingTop: paddingScroll,
               }}
               testID="error-page-listing"
            >
               <View style={{ flexDirection: 'row' }}>
                  <ScrollView>
                     <PageErrorLoad retry={reloadPage} />
                  </ScrollView>
               </View>
            </View>
         )}

         {showCards && resources.length === 0 && (
            <View
               style={{
                  flex: 1,
                  justifyContent: 'center',
                  alignItems: 'center',
                  flexGrow: 1,
                  paddingTop: paddingScroll,
               }}
               testID="not-found-page"
            >
               <View style={{ flexDirection: 'row' }}>
                  <ScrollView>
                     <PageListingNotFound />
                  </ScrollView>
               </View>
            </View>
         )}

         <CardListing {...props} />

         {showCardsSkeleton && (
            <Animated.FlatList
               contentContainerStyle={contentContainerStyle}
               renderItem={renderItemFlatListSkeleton}
               keyExtractor={keyExtractorSkeleton}
               data={skeletonResources}
               scrollEnabled={false}
            />
         )}
      </View>
   );
}

function CardListing(props: IPageListingChildrenProps) {
   const {
      renderResource,
      renderResourceSkeleton,
      viewList,
      animateScrollY,
      paddingScroll,
      scrollListingRef,
      scrollPosRef,
      scrollCardHeightRef,
      animatedNavActions,
      navActions,
      navActionsSize,
   } = props;
   const {
      resourcesTotal,
      registerOnSearch,
      skeletonResources,
      setPage,
      filters,
      starting,
      searching,
      resources,
      reloadPage,
      errorLoadData,
      errorLoadMore,
      limit,
      searchingMore,
      lastPage,
      loadNextPage,
   } = viewList;
   const onEndReachedEnabled = useRef(false);
   onEndReachedEnabled.current = !lastPage && !starting && !errorLoadMore && !errorLoadMore && !!resources.length;

   const contentContainerStyle = useMemo(
      () => ({
         paddingTop: navActions?.selected ? navActionsSize : 2 * paddingScroll,
         paddingBottom: navActions?.selected ? 2 * paddingScroll + navActionsSize : paddingScroll + navActionsSize,
      }),
      [paddingScroll, navActions?.selected],
   );
   const keyExtractor = useCallback((item: any, index: number) => `card-${item.id}`, []);
   const renderItemFlatList = useCallback(
      (item) => <View testID={`card-${item.index}`}>{renderResource(item.item, item.index)}</View>,
      [renderResource],
   );
   const onEndReached = useCallback(() => {
      if (onEndReachedEnabled.current) {
         loadNextPage();
      }
   }, []);

   // console.log(searching);

   const showPageError = errorLoadData;
   const showCards = !starting && !searching && resources && !showPageError;

   return (
      <>
         {showCards && resources.length !== 0 && (
            <Animated.FlatList
               testID="card-listing"
               // scrollEventThrottle={16}
               ref={scrollListingRef}
               contentContainerStyle={contentContainerStyle}
               // bounces={false}
               onContentSizeChange={(width, height) => {
                  scrollCardHeightRef.current = height;
               }}
               ListFooterComponent={
                  <ListFooterComponent
                     endPage={lastPage}
                     searchingMoreItems={searchingMore}
                     errorLoadMore={errorLoadMore}
                     retryMoreItems={loadNextPage}
                  />
               }
               showsVerticalScrollIndicator={false}
               onScroll={Animated.event([{ nativeEvent: { contentOffset: { y: animateScrollY } } }], {
                  useNativeDriver: true,
                  listener(event: Record<string, any>) {
                     scrollPosRef.current = event.nativeEvent.contentOffset.y;
                  },
               })}
               onEndReachedThreshold={0.4}
               onEndReached={onEndReached}
               renderItem={renderItemFlatList}
               keyExtractor={keyExtractor}
               data={resources}
            />
         )}
      </>
   );
}

const ListFooterComponent = React.memo(function ListFooterComponent({
   endPage,
   searchingMoreItems,
   errorLoadMore,
   retryMoreItems,
}: any) {
   return (
      <>
         {!endPage && !errorLoadMore && (
            <View
               style={{
                  height: RSValue(150),
                  flexDirection: 'column',
                  alignItems: 'center',
                  alignContent: 'center',
                  justifyContent: 'center',
               }}
            >
               <LoaderIcon size={48} color="#222" />
            </View>
         )}

         {errorLoadMore && (
            <View
               style={{
                  height: RSValue(150),
                  flexDirection: 'column',
                  alignItems: 'center',
                  alignContent: 'center',
               }}
            >
               <PageListingErrorLoadMore retry={retryMoreItems} />
            </View>
         )}
      </>
   );
});
