import React, {useCallback, useEffect, useMemo, useRef} from 'react';
import {View} from 'react-native';
import {useTranslation} from 'react-i18next';
import BottomSheet from '@gorhom/bottom-sheet';
import {Typography} from '@components/_core/Typography';
import {
  MentionBottomSheetFlatList,
  MentionSuggestionUserItemData,
} from '@components/_custom/MentionBottomSheetFlatList';
import {Spinner} from '@components/_HuGo/Spinner';
import {useMentionSuggestion} from '@hooks/useMentionSuggestion';
import {TaggableUser} from '@interfaces/taggedUsers';
import {
  getTaggableUserId,
  isGroupTaggableUser,
} from '@shared/utils/taggableUsers';
import {useTheme} from '@shared/theme';
import {getCompleteName, isIos} from '@shared/utils';

import {useNewPost} from '../../hooks/useNewPost';
import {styles} from './styles';
import {
  FIRST_SNAP_VISIBLE_ITEMS,
  LIST_BOTTOM_PADDING,
  LIST_ITEM_HEIGHT,
  SECOND_SNAP_VISIBLE_ITEMS,
} from './constants';

interface Props {
  groupId?: number;
}

export function Suggestions({groupId}: Props) {
  const {t} = useTranslation();
  const {theme} = useTheme();
  const {editor} = useNewPost();
  const bottomSheetRef = useRef<BottomSheet>(null);
  const dismissedQueryRef = useRef<string | undefined>(undefined);
  const {mentionQuery, suggestions, isLoadingSuggestions} =
    useMentionSuggestion(editor, groupId);

  const members = useMemo<MentionSuggestionUserItemData[]>(
    () =>
      suggestions.map((item: TaggableUser) => {
        const user = isGroupTaggableUser(item) ? item.user : item;
        return {
          id: getTaggableUserId(item),
          title: getCompleteName(user),
          profilePicture: user.profilePicture,
          pillLabel: item.isExternal ? t('group.external') : undefined,
        };
      }),
    [suggestions, t],
  );
  const keyExtractor = useCallback(
    (item: MentionSuggestionUserItemData) => item.id.toString(),
    [],
  );

  const getItemLayout = useCallback(
    (_data: unknown, index: number) => ({
      length: LIST_ITEM_HEIGHT,
      offset: LIST_ITEM_HEIGHT * index,
      index,
    }),
    [],
  );

  const onItemPress = useCallback(
    (item: MentionSuggestionUserItemData) => {
      editor.setMention({
        id: item.id.toString(),
        label: item.title,
      });
    },
    [editor],
  );

  const snapPoints = useMemo(() => {
    if (members.length === 0) {
      return [LIST_ITEM_HEIGHT * 2 + LIST_BOTTOM_PADDING];
    }

    const firstItems = Math.min(members.length, FIRST_SNAP_VISIBLE_ITEMS);
    const firstSnapPoint =
      (firstItems + 1) * LIST_ITEM_HEIGHT + LIST_BOTTOM_PADDING;
    const secondItems = Math.min(members.length, SECOND_SNAP_VISIBLE_ITEMS);
    const secondSnapPoint =
      (secondItems + 1) * LIST_ITEM_HEIGHT + LIST_BOTTOM_PADDING;
    return firstSnapPoint === secondSnapPoint
      ? [firstSnapPoint]
      : [firstSnapPoint, secondSnapPoint + (isIos ? 0 : 6)];
  }, [members.length]);

  const shouldOpenSuggestions = mentionQuery !== undefined;
  const hasDismissedCurrentQuery =
    mentionQuery !== undefined && dismissedQueryRef.current === mentionQuery;
  const shouldShowSheet = shouldOpenSuggestions && !hasDismissedCurrentQuery;
  const onClose = useCallback(() => {
    dismissedQueryRef.current = mentionQuery;
  }, [mentionQuery]);

  useEffect(() => {
    if (!shouldShowSheet) {
      bottomSheetRef.current?.close();
      return;
    }

    bottomSheetRef.current?.snapToIndex(0);
  }, [shouldShowSheet, mentionQuery, isLoadingSuggestions, suggestions]);

  useEffect(() => {
    if (mentionQuery === undefined) {
      dismissedQueryRef.current = undefined;
    }
  }, [mentionQuery]);

  return (
    <BottomSheet
      ref={bottomSheetRef}
      index={-1}
      snapPoints={snapPoints}
      enableDynamicSizing={!isIos}
      accessible={!isIos}
      enablePanDownToClose
      enableOverDrag={false}
      keyboardBehavior="interactive"
      keyboardBlurBehavior="restore"
      onClose={onClose}
      backgroundStyle={{backgroundColor: theme.background.elements.default}}
      style={[
        styles.sheetTopShadow,
        {
          shadowColor: theme.shadow['8dp'],
          borderColor: theme.shadow['8dp'],
        },
      ]}>
      {isLoadingSuggestions ? (
        <View style={[styles.loaderContainer]}>
          <Spinner />
        </View>
      ) : !members.length ? (
        <View style={styles.emptyContainer}>
          <Typography weight="semiBold">{t('general.no_results')}</Typography>
        </View>
      ) : (
        <MentionBottomSheetFlatList
          data={members}
          keyExtractor={keyExtractor}
          getItemLayout={getItemLayout}
          pageSize={members.length}
          onItemPress={onItemPress}
          listItemStyle={[
            styles.listItem,
            {backgroundColor: theme.background.elements.default},
          ]}
          contentContainerStyle={{
            backgroundColor: theme.background.elements.default,
            paddingBottom: LIST_BOTTOM_PADDING,
          }}
          isAccessible={!isIos}
        />
      )}
    </BottomSheet>
  );
}
