import React, {
  useMemo,
  createElement,
  FunctionComponent,
  useCallback,
  ComponentClass,
  useState,
} from 'react';
import {
  FlatList,
  FlatListProps,
  StyleProp,
  NativeScrollEvent,
  ViewStyle,
  ListRenderItem,
} from 'react-native';
import ActivityIndicator from '@components/ActivityIndicator';
import {useSafeAreaBottomPadding} from '@hooks/useSafeAreaBottomPadding';
import {navigate} from '@navigation/navigator';
import {useInstanceProp} from '@redux/selectors';
import {DEFAULT_THRESHOLD, Screens} from '@shared/constants';
import {
  canOpenVisualizer,
  checkEqualStrings,
  handleFileView,
  replaceForwardSlashes,
} from '@shared/utils';

import ItemSeparator from './components/ItemSeparator';
import {styles} from './styles';
import File from './components/File';
import Folder from './components/Folder';
import {FileAndAttachment, FileHierarchies} from './interfaces';

const keyExtractor = (item: FileAndAttachment) => `${item.id}`;

interface Props {
  folderId?: number;
  files?: FileAndAttachment[];
  loading?: boolean;
  onScroll?: ({nativeEvent}: {nativeEvent: NativeScrollEvent}) => void;
  loadingMore?: boolean;
  searchTerm?: string;
  handleClickFile?: (value: FileAndAttachment, funcValue: () => void) => void;
  handleClickFolder?: (id: number, name: string) => void;
  clickFileCallback?: (value: FileAndAttachment) => void;
  emptyComponent?:
    | string
    | FunctionComponent
    | ComponentClass<unknown, unknown>;
  containerStyle?: StyleProp<ViewStyle>;
  getSubtitle?: (val: {folderId: number}) => string;
  showFinalLine?: boolean;
  showSubtitle?: boolean;
  withPreview?: boolean;
  flatListProps?: Partial<FlatListProps<FileAndAttachment>>;
}

/**
 * @deprecated - Use `_custom/FileList`, it's build with HuGo :)
 */
function FileList({
  folderId,
  files,
  loading,
  onScroll = () => {},
  loadingMore = false,
  searchTerm,
  handleClickFile: customizedHandleClickFile,
  handleClickFolder,
  clickFileCallback,
  emptyComponent,
  containerStyle,
  getSubtitle,
  showFinalLine,
  showSubtitle = true,
  withPreview,
  flatListProps,
}: Props) {
  const bottom = useSafeAreaBottomPadding();
  const hideFileDownload = useInstanceProp('hideFileDownload');
  const [openedFileName, setOpenedFileName] = useState('');
  const data = useMemo(
    () =>
      files?.map(file =>
        file.name ? {...file, name: replaceForwardSlashes(file.name)} : file,
      ) || [],
    [files],
  );

  const handlePressFile = useCallback(
    (item: FileAndAttachment) => () => {
      if (customizedHandleClickFile) {
        setOpenedFileName(item.name);
        customizedHandleClickFile(item, () => setOpenedFileName(''));
      } else {
        if (canOpenVisualizer(item) || hideFileDownload) {
          navigate(Screens.FILE_VISUALIZER, {file: item});
        } else {
          handleFileView(item, setOpenedFileName);
        }
        clickFileCallback?.(item);
      }
    },
    [clickFileCallback, customizedHandleClickFile, hideFileDownload],
  );

  const renderItem: ListRenderItem<FileAndAttachment> = useCallback(
    ({item}) => {
      const showParentName =
        !!searchTerm && folderId !== item.parentId && !!item.parentName;
      return item.type === (FileHierarchies.Folder as string) ? (
        <Folder
          item={item}
          onPress={() => handleClickFolder?.(item.id, item.name)}
          searchTerm={searchTerm}
          showParentName={showParentName}
        />
      ) : (
        <File
          item={item}
          searchTerm={searchTerm}
          showSubtitle={showSubtitle}
          getSubtitle={getSubtitle}
          withPreview={withPreview}
          onPress={handlePressFile(item)}
          loading={checkEqualStrings(openedFileName, item.name)}
          showParentName={showParentName}
        />
      );
    },
    [
      folderId,
      getSubtitle,
      handleClickFolder,
      handlePressFile,
      withPreview,
      openedFileName,
      searchTerm,
      showSubtitle,
    ],
  );

  return loading ? (
    <ActivityIndicator fullScreen />
  ) : (
    <FlatList
      data={data}
      contentContainerStyle={[
        styles.container,
        containerStyle || {paddingBottom: bottom},
      ]}
      ListFooterComponent={
        <>
          {showFinalLine && !!data?.length && <ItemSeparator />}
          <ActivityIndicator isVisible={loadingMore} />
        </>
      }
      ListEmptyComponent={emptyComponent ? createElement(emptyComponent) : null}
      renderItem={renderItem}
      keyExtractor={keyExtractor}
      onScroll={onScroll}
      onEndReachedThreshold={DEFAULT_THRESHOLD}
      ItemSeparatorComponent={ItemSeparator}
      showsVerticalScrollIndicator={false}
      {...flatListProps}
    />
  );
}

export default FileList;
