import React, {useState, useMemo, useCallback} from 'react';
import {FlatListProps, StyleProp, StyleSheet, TextStyle} from 'react-native';
import {BottomSheetFlatList as NativeBottomSheetFlatList} from '@gorhom/bottom-sheet';
import {MODAL_SPACING} from '@components/Modals/constants';
import SearchInput from '@components/SearchInput';
import Text from '@components/Text';

export interface BottomSheetFlatListProps<ItemT = unknown>
  extends Omit<FlatListProps<ItemT>, 'children'> {
  data: ArrayLike<ItemT> | null | undefined;
  /**
   * Show search input. Use `filterRule` to filter data locally or `onFilterText` to filter data asynchronously.
   */
  filterable?: boolean;
  /**
   * Filter callback when a search text is typed.
   * @param item - Current item
   * @param filterText - typed text in lower case.
   */
  filterRule?: (item: ItemT, filterText: string) => boolean;
  /**
   * Filter data asynchronously. When this is defined, `filterRule` has no effect.
   * @param filterText - typed text in lower case
   */
  onFilterText?: (filterText: string) => void;
  searchPlaceholder?: string;
  paddingBottom?: number;
  title?: string;
  titleStyle?: StyleProp<TextStyle>;
}

/**
 * @deprecated Use `_HuGo/Modals` instead
 */
export function BottomSheetFlatList<T extends object>({
  data,
  title,
  titleStyle,
  filterable,
  searchPlaceholder,
  filterRule,
  contentContainerStyle,
  ListHeaderComponent,
  onFilterText,
  paddingBottom,
  ...props
}: BottomSheetFlatListProps<T>) {
  const [filter, setFilter] = useState('');

  const filteredData = useMemo(() => {
    if (
      onFilterText ||
      !filterable ||
      !filter ||
      !filterRule ||
      !Array.isArray(data)
    ) {
      return data;
    }
    return data.filter(item => filterRule(item, filter.toLowerCase()));
  }, [data, filter, filterRule, filterable, onFilterText]);

  const onSearchChange = useCallback(
    (value: string) => {
      setFilter(value);
      onFilterText?.(value);
    },
    [onFilterText],
  );

  const flattenContentContainerStyle = StyleSheet.flatten([
    styles.content,
    contentContainerStyle,
    {paddingBottom},
  ]);

  return (
    <NativeBottomSheetFlatList
      data={filteredData}
      contentContainerStyle={flattenContentContainerStyle}
      ListHeaderComponent={
        <>
          {!!title && (
            <Text variant="h6" style={[styles.title, titleStyle]}>
              {title}
            </Text>
          )}
          {filterable && (
            <SearchInput
              value={filter}
              onChange={onSearchChange}
              placeholder={searchPlaceholder}
              style={styles.searchBox}
              withClose={!!filter.length}
            />
          )}
          {ListHeaderComponent}
        </>
      }
      {...props}
    />
  );
}

const styles = StyleSheet.create({
  searchBox: {margin: 0, marginBottom: 8},
  content: {paddingHorizontal: MODAL_SPACING.modalPadding},
  title: {marginBottom: MODAL_SPACING.modalPadding},
});
