import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
import {View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {ScrollView} from 'react-native-gesture-handler';
import {useNavigation} from '@react-navigation/native';
import {
  Typography,
  Pressable,
  Dialog,
  Avatar,
  Spinner,
  List,
  Pill,
} from '@components';
import {Reaction} from '@interfaces/reaction';
import {User} from '@interfaces/user';
import {useTheme, SPACING} from '@shared/theme';
import {Screens, windowDimensions} from '@shared/constants';

import {styles} from './styles';

const REACTION_ITEM_WIDTH = 55;

type UserPick = Pick<
  User,
  'id' | 'firstName' | 'lastName' | 'profilePicture'
> & {
  isExternal?: boolean;
};

type QueryDataType = {
  data?: Nullable<UserPick[]>;
  isLoading: boolean;
  isFetchingNextPage?: boolean;
  getNextPage?: () => void;
};

interface ReactionsSummaryBottomSheetProps {
  visible: boolean;
  reactions: Reaction[];
  onClose: () => void;
  setSelectedReaction: (reaction: string) => void;
  selectedReaction: Nullable<string>;
  queryData: QueryDataType;
}

interface TabItem {
  id: string;
  emoji: string;
  count: number;
  label: string;
}

export const ReactionsSummaryBottomSheet = ({
  visible,
  reactions,
  queryData,
  onClose,
  setSelectedReaction,
  selectedReaction,
}: ReactionsSummaryBottomSheetProps) => {
  const {theme} = useTheme();
  const navigation = useNavigation();
  const scrollViewRef = useRef<ScrollView>(null);
  const {t} = useTranslation();
  const [activeTab, setActiveTab] = useState<Nullable<string>>(null);
  const {data, isLoading, isFetchingNextPage, getNextPage} = queryData;

  const scrollToReaction = useCallback(() => {
    const index = reactions.findIndex(
      reaction => reaction.emoji === selectedReaction,
    );
    const timer = setTimeout(() => {
      scrollViewRef.current?.scrollTo({
        x: (index - 3) * REACTION_ITEM_WIDTH,
        y: 0,
        animated: true,
      });
    }, 200);
    return () => clearTimeout(timer);
  }, [reactions, selectedReaction]);

  useEffect(() => {
    if (reactions.length > 0) {
      setActiveTab(selectedReaction);
      scrollToReaction();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const onSelectTab = useCallback(
    (tab: TabItem) => () => {
      setActiveTab(tab.emoji);
      setSelectedReaction(tab.emoji);
    },
    [setSelectedReaction],
  );

  const tabItems = useMemo(() => {
    return reactions.map(reaction => ({
      id: reaction.emoji,
      label: '',
      emoji: reaction.emoji,
      count: reaction.count,
    }));
  }, [reactions]);

  const renderReactionTab = useCallback(
    (tab: TabItem) => {
      const isActive = tab.emoji === activeTab;
      return (
        <Pressable
          key={tab.emoji}
          style={[
            styles.tab,
            isActive && [
              styles.selectedTab,
              {borderBottomColor: theme.primary},
            ],
          ]}
          onPress={onSelectTab(tab)}>
          <Typography variant="xxs">{tab.emoji}</Typography>
          <Typography
            variant="xs"
            color={isActive ? theme.primary : theme.secondaryText}>
            {tab.count}
          </Typography>
        </Pressable>
      );
    },
    [onSelectTab, theme.primary, theme.secondaryText, activeTab],
  );

  const onPressUser = useCallback(
    (userId: number) => () => {
      onClose();
      navigation.navigate(Screens.PROFILE, {userId});
    },
    [navigation, onClose],
  );

  const renderUserWithReaction = useCallback(
    ({item}: {item: UserPick}) => {
      return (
        <Pressable
          style={styles.userItem}
          onPress={item.isExternal ? undefined : onPressUser(item.id)}>
          <Avatar
            name={{firstName: item.firstName, lastName: item.lastName}}
            url={item.profilePicture}
          />
          <Typography style={styles.userName}>
            {item.firstName} {item.lastName}
          </Typography>
          {item.isExternal && (
            <Pill variant="neutral" size="sm" text={t('group.external')} />
          )}
        </Pressable>
      );
    },
    [onPressUser, t],
  );

  return (
    <Dialog
      isVisible={visible}
      onClose={onClose}
      title={t('acknowledgements.reactions')}
      contentStyle={{
        paddingHorizontal: SPACING.x2,
        maxHeight: windowDimensions.height * 0.9,
      }}>
      {/* TODO: use tabs from HuGO */}
      <View
        style={[
          styles.tabsContainer,
          {borderBottomColor: theme.border.neutral.default},
        ]}>
        <ScrollView
          ref={scrollViewRef}
          horizontal
          showsHorizontalScrollIndicator={false}>
          {tabItems.map(renderReactionTab)}
        </ScrollView>
      </View>
      <View style={styles.reactionsContainer}>
        {isLoading ? (
          <View style={styles.loadingContainer}>
            <Spinner />
          </View>
        ) : (
          <View style={styles.listContainer}>
            <List
              data={data}
              onNextPage={getNextPage}
              isFetchingNextPage={isFetchingNextPage}
              isLoading={isLoading}
              renderItem={renderUserWithReaction}
              withDivider={false}
              style={styles.list}
              showsVerticalScrollIndicator={false}
              bounces={false}
              FetchingNextPageLoader={<Spinner />}
            />
          </View>
        )}
      </View>
    </Dialog>
  );
};
