import React, {memo, useCallback, useState} from 'react';
import {ListRenderItem, StyleSheet, View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import {useNavigation} from '@react-navigation/native';
import {IconX} from '@tabler/icons-react-native';
import {
  IconButton,
  InputSearch,
  List,
  ListItem,
  Spinner,
  Typography,
} from '@components';
import {useInfiniteQuery} from '@hooks/queries/useInfiniteQuery';
import {useDebounceCallback} from '@hooks/useDebounceCallback';
import {useGoBack} from '@hooks/useGoBack';
import {User} from '@interfaces/user';
import {Navigation} from '@interfaces/navigation';
import {useCreateChat} from '@modules/chat/hooks';
import {getUserList} from '@modules/chat/services';
import {CHAT_QUERY_KEYS} from '@modules/chat/constants';
import {getShortName} from '@shared/utils';
import {Screens} from '@shared/constants';
import {ICON_SIZES, SPACING} from '@shared/theme';

import ListHeader from './components/ListHeader';

interface Props {
  onCreateTicketPress?: () => void;
  onCreateGroupPress?: () => void;
}

const SelectUserTab = (props: Props) => {
  const {t} = useTranslation();
  const {bottom} = useSafeAreaInsets();
  const navigation = useNavigation<Navigation['navigation']>();
  const {goBack} = useGoBack();
  const [searchText, setSearchText] = useState('');
  const [selectedUserId, setSelectedUserId] = useState<number>();
  const {createChat, isLoading: isCreateLoading} = useCreateChat({
    onSuccess: chatId => {
      navigation.replace(Screens.CHAT_DETAIL, {
        chatId,
      });
    },
    onSettled: () => {
      setSelectedUserId(undefined);
    },
  });

  const {
    data,
    isLoading,
    isError,
    getNextPage,
    isRefreshing,
    hasNextPage,
    isFetchingNextPage,
  } = useInfiniteQuery(CHAT_QUERY_KEYS.searchUsers(searchText), ({page}) =>
    getUserList({page, q: searchText}),
  );
  const lastItemIndex = (data?.length || 0) - 1;

  const {debouncedCallback: debounceSearch} = useDebounceCallback(
    (text: string) => {
      setSearchText(text);
    },
  );

  const onUserPress = useCallback(
    (userId: number) => {
      if (!isCreateLoading) {
        setSelectedUserId(userId);
        createChat(userId);
      }
    },
    [createChat, isCreateLoading],
  );

  const keyExtractor = useCallback((item: User) => item.id.toString(), []);

  const renderItem: ListRenderItem<User> = useCallback(
    ({item, index}) => {
      const name = getShortName(item);
      const isCreatingChatUser = selectedUserId === item.id;
      return (
        <ListItem
          title={name}
          avatar={{
            name,
            url: item.profilePicture,
          }}
          presentation="card"
          onItemPress={() => onUserPress(item.id)}
          isFirstItem={index === 0}
          isLastItem={index === lastItemIndex}
          withRightIcon={!isCreatingChatUser}>
          {isCreatingChatUser ? <Spinner /> : null}
        </ListItem>
      );
    },
    [lastItemIndex, selectedUserId, onUserPress],
  );

  return (
    <View style={styles.container}>
      <View style={styles.header}>
        <View style={styles.headerLeft} />
        <Typography variant="m" weight="semiBold">
          {t('chats.new_chat')}
        </Typography>
        <IconButton Icon={IconX} onPress={goBack} variant="flat" />
      </View>
      <InputSearch
        value={searchText}
        placeholder={t('chat.search.by_name')}
        onChangeText={debounceSearch}
        style={styles.inputSearch}
      />
      <List
        presentation="card"
        data={data}
        isLoading={isLoading}
        isError={isError}
        isRefreshing={isRefreshing}
        keyExtractor={keyExtractor}
        renderItem={renderItem}
        onNextPage={getNextPage}
        hasNextPage={hasNextPage}
        isFetchingNextPage={isFetchingNextPage}
        style={[styles.list, {paddingBottom: bottom + SPACING.x2}]}
        ListHeaderComponent={<ListHeader {...props} searchText={searchText} />}
        paginationType="button"
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {flex: 1},
  header: {
    padding: SPACING.x2,
    paddingTop: SPACING.x3,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
  },
  inputSearch: {
    paddingHorizontal: SPACING.x2,
  },
  list: {paddingTop: SPACING.x2},
  headerLeft: {width: ICON_SIZES.x6},
});

export default memo(SelectUserTab);
