import React, { RefObject } from 'react';
import { FlashList, MasonryFlashList } from '@shopify/flash-list';
import {
  NativeSyntheticEvent,
  NativeScrollEvent,
  StyleSheet,
} from 'react-native';
import { useSelector } from 'react-redux';
import { Divider, HelperText } from 'react-native-paper';
import { useSafeAreaFrame } from 'react-native-safe-area-context';
import { Meme } from '../../../database';
import { RootState } from '../../../state';
import { VIEW } from '../../../types';
import { getFlashListItemHeight } from '../../../utilities';
import MemesMasonryItem from './memesMasonryItem';
import MemesGridItem from './memesGridItem';
import MemesListItem from './memesListItem';
import { AndroidScoped } from 'react-native-file-access';

const sharedMemesListStyles = StyleSheet.create({
  flashList: {
    paddingBottom: 100,
  },
  helperText: {
    textAlign: 'center',
    marginVertical: 15,
  },
});

const memesMasonryListStyles = StyleSheet.create({
  flashList: {
    // Needed to prevent fucky MasonryFlashList, see https://github.com/Shopify/flash-list/issues/876
    paddingHorizontal: 0.1,
  },
});

const memesGridListStyles = StyleSheet.create({
  flashList: {
    paddingHorizontal: 2.5,
  },
});

const memesListListStyles = StyleSheet.create({
  flashList: {
    paddingHorizontal: 5,
  },
});

const MemesList = ({
  memes,
  flashListRef,
  flashListPadding,
  handleScroll,
  focusMeme,
}: {
  memes: Realm.Results<Meme & Realm.Object<Meme>>;
  flashListRef: RefObject<FlashList<Meme>>;
  flashListPadding: number;
  handleScroll: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
  focusMeme: (index: number) => void;
}) => {
  const { height, width } = useSafeAreaFrame();
  const view = useSelector((state: RootState) => state.memes.view);
  const masonryColumns = useSelector(
    (state: RootState) => state.settings.masonryColumns,
  );
  const gridColumns = useSelector(
    (state: RootState) => state.settings.gridColumns,
  );
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
  const storageUri = useSelector(
    (state: RootState) => state.settings.storageUri,
  )!;

  return (
    <>
      {view === VIEW.MASONRY && (
        <MasonryFlashList
          ref={flashListRef}
          data={memes}
          key={masonryColumns}
          estimatedItemSize={getFlashListItemHeight(masonryColumns)}
          estimatedListSize={{
            height,
            width: width * 0.92,
          }}
          numColumns={masonryColumns}
          showsVerticalScrollIndicator={false}
          renderItem={({ item: meme, index }) => (
            <MemesMasonryItem
              meme={meme}
              focusMeme={() => focusMeme(index)}
              uri={AndroidScoped.appendPath(storageUri, meme.filename)}
              columns={masonryColumns}
            />
          )}
          contentContainerStyle={{
            paddingTop: flashListPadding,
            ...sharedMemesListStyles.flashList,
            ...memesMasonryListStyles.flashList,
          }}
          ListEmptyComponent={() => (
            <HelperText type={'info'} style={sharedMemesListStyles.helperText}>
              No memes found
            </HelperText>
          )}
          onScroll={handleScroll}
          fadingEdgeLength={100}
          overScrollMode="never"
        />
      )}
      {view === VIEW.GRID && (
        <FlashList
          ref={flashListRef}
          data={memes}
          key={gridColumns}
          estimatedItemSize={getFlashListItemHeight(gridColumns)}
          estimatedListSize={{
            height: height,
            width: width * 0.92,
          }}
          numColumns={gridColumns}
          showsVerticalScrollIndicator={false}
          renderItem={({ item: meme, index }) => (
            <MemesGridItem
              meme={meme}
              focusMeme={() => focusMeme(index)}
              uri={AndroidScoped.appendPath(storageUri, meme.filename)}
              columns={gridColumns}
            />
          )}
          contentContainerStyle={{
            paddingTop: flashListPadding,
            ...sharedMemesListStyles.flashList,
            ...memesGridListStyles.flashList,
          }}
          ListEmptyComponent={() => (
            <HelperText type={'info'} style={sharedMemesListStyles.helperText}>
              No memes found
            </HelperText>
          )}
          onScroll={handleScroll}
          fadingEdgeLength={100}
          overScrollMode="never"
        />
      )}
      {view === VIEW.LIST && (
        <FlashList
          ref={flashListRef}
          data={memes}
          estimatedItemSize={90}
          estimatedListSize={{
            height: height,
            width: width * 0.92,
          }}
          showsVerticalScrollIndicator={false}
          renderItem={({ item: meme, index }) => (
            <MemesListItem
              meme={meme}
              focusMeme={() => focusMeme(index)}
              uri={AndroidScoped.appendPath(storageUri, meme.filename)}
            />
          )}
          ItemSeparatorComponent={() => <Divider />}
          contentContainerStyle={{
            paddingTop: flashListPadding,
            ...sharedMemesListStyles.flashList,
            ...memesListListStyles.flashList,
          }}
          ListEmptyComponent={() => (
            <HelperText type={'info'} style={sharedMemesListStyles.helperText}>
              No memes found
            </HelperText>
          )}
          onScroll={handleScroll}
          fadingEdgeLength={100}
          overScrollMode="never"
        />
      )}
    </>
  );
};

export default MemesList;
