import React, {
  useCallback,
  useEffect,
  useMemo,
  useState,
  ReactElement,
} from 'react';
import {TouchableOpacity, View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {shallowEqual, useDispatch} from 'react-redux';
import UsersSectionList from '@components/UsersSectionList';
import Text from '@components/Text';
import Icon from '@components/Icon';
import Tooltip from '@components/Tooltip';
import {useGetUsersPublic} from '@hooks/useGetUsersPublic';
import {useGoBack} from '@hooks/useGoBack';
import {Navigation} from '@interfaces/navigation';
import SegmentationItemsList from '@modules/post/screens/PublishPost/components/SegmentationDialog/components/SegmentationItemsList';
import PublishButton from '@modules/post/screens/PublishPost/components/PublishButton';
import {
  getSegmentationUsers,
  getSegmentationUsersCount,
  setSegmentationItemIds,
} from '@modules/post/store';
import {Tabs} from '@modules/post/constants';
import {useAppSelector} from '@redux/utils';
import {Screens} from '@shared/constants';
import {useTheme} from '@shared/theme';
import {
  capitalize,
  getCheckedSegmentationItems,
  getModifiedSegmentationItems,
} from '@shared/utils';
import {SHARED_STRINGS} from '@shared/strings';

import {styles} from './styles';
import Tag from './components/Tag';
import HeaderOption from './components/HeaderOption';

function Segmentation({navigation, route}: Navigation<Screens.SEGMENTATION>) {
  const {t} = useTranslation();
  const dispatch = useDispatch();
  const {goBack} = useGoBack();
  const {theme} = useTheme();
  const {
    loadingSegmentationUsers,
    loadingMoreSegmentationUsers,
    segmentationUsers,
    segmentationItems,
    segmentationItemIds,
  } = useAppSelector(({posts}) => posts, shallowEqual);
  const canSegmentate = useAppSelector(
    ({user}) => user.permissions.CAN_SEGMENTATE,
  );
  const [selectedTab, setSelectedTab] = useState(Tabs.FIRST);
  const [showTooltip, setShowTooltip] = useState(false);
  const {data: usersPublic = []} = useGetUsersPublic();
  const {setSegmentationItems} = route.params;
  const hasSegmentationUsers = !!segmentationUsers.users.length;
  const usersToShow = useMemo(
    () =>
      hasSegmentationUsers
        ? segmentationUsers.users
        : [{title: '', data: usersPublic}],
    [hasSegmentationUsers, segmentationUsers.users, usersPublic],
  );

  useEffect(() => {
    const headerLeft = () => (
      <View style={styles.headerLeftContainer}>
        <Text style={styles.headerLeftText}>{t('post.segmentation')}</Text>
        <TouchableOpacity
          onPress={() => {
            setShowTooltip(true);
            setTimeout(() => setShowTooltip(false), 3000);
          }}>
          <Icon name="help" size="sm" color={theme.text.neutral.lighter} />
        </TouchableOpacity>
        <Tooltip
          visible={showTooltip}
          contrainerStyle={styles.animatedContainer}
          text={t('post.segmentation_tooltip')}
        />
      </View>
    );
    const headerRight = () => (
      <PublishButton
        onPress={goBack}
        text={capitalize(t(SHARED_STRINGS.ACCEPT).toUpperCase())!}
        style={styles.rightHeader}
      />
    );

    navigation.setOptions({headerLeft, headerRight});
  }, [navigation, goBack, showTooltip, t, theme.text.neutral.lighter]);

  const setNewSegItems = (index: number, groupIndex: number) => () => {
    const modifiedSegItems = getModifiedSegmentationItems(
      segmentationItems,
      index,
      groupIndex,
    );
    setSegmentationItems(modifiedSegItems);
    const newSegmentationItemIds: string = (
      canSegmentate ? getCheckedSegmentationItems(modifiedSegItems) : []
    ).reduce((accum: string, current) => {
      return accum ? `${accum}, ${current}` : `${current}`;
    }, '');
    dispatch(
      selectedTab === Tabs.FIRST
        ? getSegmentationUsersCount(
            newSegmentationItemIds
              ? {
                  segmentationItemIds: newSegmentationItemIds,
                  includeLoggedUser: true,
                }
              : {},
          )
        : getSegmentationUsers({
            segmentationItemIds: newSegmentationItemIds,
            includeLoggedUser: true,
          }),
    );
    dispatch(setSegmentationItemIds(newSegmentationItemIds));
  };

  const getTags = () => {
    const tags: ReactElement[] = [];
    segmentationItems.forEach((item, index) =>
      item.items.forEach(
        (group, groupIndex) =>
          group.checked &&
          tags.push(
            <Tag
              key={`${groupIndex}-${index}`}
              text={group.name}
              onClose={setNewSegItems(index, groupIndex)}
            />,
          ),
      ),
    );
    return tags.length ? tags : <Tag text={t('post.all_the_company')} />;
  };

  const headerOptionPress = (tab: Tabs) => () => setSelectedTab(tab);
  const onGetMoreUsers = (page: number) => {
    hasSegmentationUsers &&
      !loadingMoreSegmentationUsers &&
      dispatch(
        getSegmentationUsers({
          segmentationItemIds: segmentationItemIds || undefined,
          page,
          includeLoggedUser: true,
        }),
      );
  };
  const onPressSecondTab = useCallback(() => {
    headerOptionPress(Tabs.SECOND)();
    dispatch(
      getSegmentationUsers({
        segmentationItemIds: segmentationItemIds || '',
        includeLoggedUser: true,
      }),
    );
  }, [dispatch, segmentationItemIds]);

  return (
    <View
      style={[
        styles.container,
        {backgroundColor: theme.background.elements.default},
      ]}>
      <View style={styles.subContainer}>
        <Icon
          name="groupsFill"
          color={theme.text.neutral.default}
          style={styles.audienceIcon}
        />
        <Text>
          <Text variant="subtitle1">{`${t('post.scope')}: `}</Text>
          {`${segmentationUsers.count} ${t(SHARED_STRINGS.PEOPLE)}`}
        </Text>
      </View>
      <View style={styles.tagsContainer}>{getTags()}</View>
      <View style={styles.optionsContainer}>
        <HeaderOption
          onPress={headerOptionPress(Tabs.FIRST)}
          selected={selectedTab === Tabs.FIRST}
          text={t(SHARED_STRINGS.GROUPS)}
        />
        <HeaderOption
          onPress={onPressSecondTab}
          selected={selectedTab === Tabs.SECOND}
          text={capitalize(t(SHARED_STRINGS.USERS))}
        />
      </View>
      {selectedTab === Tabs.FIRST ? (
        <SegmentationItemsList
          segmentationItems={segmentationItems}
          setSegmentationItems={setNewSegItems}
          contentContainerStyle={styles.segContentContainer}
          style={styles.segContainer}
        />
      ) : (
        <UsersSectionList
          loading={loadingSegmentationUsers}
          loadingMore={loadingMoreSegmentationUsers}
          users={usersToShow}
          getMoreUsers={onGetMoreUsers}
        />
      )}
    </View>
  );
}

export default Segmentation;
