import {useCallback, useEffect, useMemo, useState} from 'react';
import {ListRenderItem} from 'react-native';
import {useTranslation} from 'react-i18next';
import {Menu} from '@components';
import {User} from '@interfaces/user';
import {TimeOffTab} from '@modules/timeOff/interfaces';

import CheckboxListSk from '../CheckboxListSk';
import CheckUser from './components/CheckUser';
import {styles} from './styles';

const keyExtractor = (user: User) => `${user.id}`;

const SNAP_POINTS = ['100%'];

interface Props {
  fromTab?: TimeOffTab;
  selectedUsers: User[];
  onSelectUsers: (users: User[]) => void;
  isVisible: boolean;
  data: User[];
  onEndReached: () => void;
  isFetchingNextPage: boolean;
  isLoading: boolean;
  onFilterText: (text: string) => void;
  onCloseWithoutApply: () => void;
  onResetSelection?: () => void;
  title?: string;
  searchPlaceholder?: string;
  singleSelection?: boolean;
}

function UsersMenu({
  selectedUsers,
  onSelectUsers,
  onResetSelection,
  isVisible,
  data,
  onEndReached,
  isFetchingNextPage,
  isLoading,
  onFilterText,
  onCloseWithoutApply,
  title,
  searchPlaceholder,
  singleSelection = false,
}: Props) {
  const {t} = useTranslation();
  const [newUsers, setNewUsers] = useState<User[]>([]);
  const getValidSelectedUsers = useCallback(
    (users: User[]) => (singleSelection ? users.slice(0, 1) : users),
    [singleSelection],
  );

  useEffect(() => {
    // If the user closes the menu, we reset with the current selected users
    if (!isVisible) {
      setNewUsers(getValidSelectedUsers(selectedUsers));
    }
  }, [selectedUsers, isVisible, getValidSelectedUsers]);

  const onPressUser = useCallback(
    (user: User) => () => {
      setNewUsers(prevNewUsers =>
        prevNewUsers.some(prevNewUser => prevNewUser.id === user.id)
          ? prevNewUsers.filter(prevNewUser => prevNewUser.id !== user.id)
          : singleSelection
          ? [user]
          : prevNewUsers.concat(user),
      );
    },
    [singleSelection],
  );

  const renderItem: ListRenderItem<User> = useCallback(
    ({item}) => (
      <CheckUser
        isChecked={newUsers.some(user => user.id === item.id)}
        onPressUser={onPressUser(item)}
        singleSelection={singleSelection}
        user={item}
      />
    ),
    [newUsers, onPressUser, singleSelection],
  );

  const handleSelectUsers = useCallback(() => {
    onSelectUsers(getValidSelectedUsers(newUsers));
  }, [onSelectUsers, newUsers, getValidSelectedUsers]);

  const footer = useMemo(
    () => ({
      primaryButton: {
        disabled: !newUsers.length,
        onPress: handleSelectUsers,
        text: t('general.select'),
      },
      secondaryButton: onResetSelection
        ? {
            disabled: !newUsers.length,
            onPress: onResetSelection,
            text: t('general.reset_selection'),
          }
        : undefined,
    }),
    [newUsers.length, handleSelectUsers, onResetSelection, t],
  );

  return (
    <Menu
      filterable
      contentContainerStyle={styles.menuContentContainer}
      data={data}
      footer={footer}
      isVisible={isVisible}
      keyExtractor={keyExtractor}
      ListEmptyComponent={isLoading ? <CheckboxListSk withAvatar /> : undefined}
      ListFooterComponent={
        isFetchingNextPage ? <CheckboxListSk withAvatar /> : undefined
      }
      onClose={onCloseWithoutApply}
      onEndReached={isVisible ? onEndReached : undefined}
      onFilterText={onFilterText}
      renderItem={renderItem}
      searchPlaceholder={searchPlaceholder || t('general.search_people')}
      showsVerticalScrollIndicator={false}
      snapPoints={SNAP_POINTS}
      title={title || t('time_off.people')}
    />
  );
}

export default UsersMenu;
