import React from 'react';
import type { SectionList, SectionListRenderItemInfo } from 'react-native';
import { Dimensions } from 'react-native';
import type { SingleSelectProps } from '.';
import type { BaseOptionListProps } from '../BaseOptionList';
import type { SelectOptionType, SectionType } from '../types';
import Option from './Option';
import { StyledOptionList } from './StyledSingleSelect';
import { deepCompareValue } from '../../../utils/helpers';

type OptionListProps<V, T extends SelectOptionType<V>> = Pick<
  SingleSelectProps<V, T>,
  | 'keyExtractor'
  | 'loading'
  | 'onEndReached'
  | 'onQueryChange'
  | 'value'
  | 'renderOption'
> & {
  onPress: (value: V | null) => void;
  sectionListRef?: React.RefObject<SectionList<T, SectionType> | null>;
} & BaseOptionListProps<V, T>;

const OptionList = <V, T extends SelectOptionType<V>>({
  keyExtractor,
  loading,
  onEndReached,
  onPress,
  onQueryChange,
  sections,
  renderOption,
  value,
  sectionListRef,
  ...rest
}: OptionListProps<V, T>) => {
  const renderItem = (info: SectionListRenderItemInfo<T, SectionType>) => {
    const { item } = info;
    const selected = deepCompareValue(item.value, value);
    const onItemPress = () => {
      if (value === item.value) {
        onPress(null);
      } else {
        onPress(item.value);
      }
    };

    return renderOption ? (
      renderOption({ ...info, selected, onPress: onItemPress })
    ) : (
      <Option
        selected={selected}
        text={item.text}
        disabled={item.disabled}
        onPress={onItemPress}
        highlighted={item.highlighted}
      />
    );
  };

  return (
    <StyledOptionList<V, T>
      keyExtractor={keyExtractor}
      loading={loading}
      onEndReached={onEndReached}
      onQueryChange={onQueryChange}
      sections={sections}
      renderItem={renderItem}
      sectionListRef={sectionListRef}
      style={{
        ...(onQueryChange ? { height: Dimensions.get('screen').height } : {}),
      }}
      {...rest}
    />
  );
};

export default OptionList;
