import React, {useCallback, useEffect, useMemo, useState} from 'react';
import {View, TouchableOpacity} from 'react-native';
import {useRoute} from '@react-navigation/native';
import {useAppSelector} from '@redux/utils';
import {SocketConnection} from '@config/socket/socket';
import {
  ModulesNotifications,
  getModuleNotifications,
  clearModuleNotifications,
} from '@shared/notifications';
import {shortenText} from '@shared/utils';
import {Screens} from '@shared/constants';
import {EventsSocketsType} from '@config/constants';
import RedBubble from '@components/RedBubble';
import FolderIcon from '@assets/folder.svg';
import Icon from '@components/Icon';
import Text from '@components/Text';
import {ERROR} from '@shared/strings';

import {
  NAME_LIMIT,
  FOLDER_ICON_SIZE,
  SMALL_FOLDER_ICON_SIZE,
} from '../../constants';
import {getComponentsBySearchTerm} from '../../utils';
import {File} from '../../interfaces';

import {styles} from './styles';

const socket = new SocketConnection();

interface Props {
  item: File;
  onPress: () => void;
  searchTerm?: string;
  showParentName?: boolean;
}

function Folder({
  item: {name, parentName, id},
  onPress,
  searchTerm,
  showParentName,
}: Props) {
  const route = useRoute();
  const VIEW_DOCUMENT = useAppSelector(
    ({user}) => user.permissions.VIEW_DOCUMENT,
  );
  const [unreadDocuments, setUnreadDocuments] = useState(0);
  const folderName = useMemo(() => shortenText(name, NAME_LIMIT), [name]);
  const indexOfSearchTerm = useMemo(
    () =>
      searchTerm && folderName.toLowerCase().indexOf(searchTerm.toLowerCase()),
    [folderName, searchTerm],
  );
  const isInDocuments = route.name === Screens.DOCUMENTS && VIEW_DOCUMENT;

  const getDocumentNotifications = useCallback(async () => {
    if (isInDocuments) {
      const response = await getModuleNotifications<{
        documentNotifications: number;
      }>(ModulesNotifications.DOCUMENT, id);
      response !== ERROR && setUnreadDocuments(response.documentNotifications);
    }
  }, [id, isInDocuments]);

  useEffect(() => {
    socket.listenEvent(
      EventsSocketsType.RED_BUBBLE_CLEARED,
      (data: {type: string}) =>
        data.type === ModulesNotifications.DOCUMENT &&
        getDocumentNotifications(),
    );
    socket.listenEvent(
      EventsSocketsType.DOCUMENT_CREATED,
      getDocumentNotifications,
    );
    socket.listenEvent(
      EventsSocketsType.DOCUMENT_DELETED,
      getDocumentNotifications,
    );
    socket.listenEvent(
      EventsSocketsType.DOCUMENT_UPDATED,
      getDocumentNotifications,
    );
    getDocumentNotifications();
  }, [getDocumentNotifications]);

  const renderText = () =>
    searchTerm && indexOfSearchTerm && indexOfSearchTerm >= 0
      ? getComponentsBySearchTerm(
          folderName,
          indexOfSearchTerm,
          searchTerm,
        ).map(({text, bold}, index) => (
          <Text key={index} weight={bold ? 'bold' : 'regular'}>
            {text}
          </Text>
        ))
      : folderName;
  const width = unreadDocuments ? '73%' : isInDocuments ? '73%' : '80%';

  const handleOnPress = async () => {
    if (isInDocuments) {
      await clearModuleNotifications(ModulesNotifications.DOCUMENT, id);
      getDocumentNotifications();
    }
    onPress();
  };

  return (
    <TouchableOpacity onPress={handleOnPress} style={styles.itemContainer}>
      <View style={styles.folderAndName}>
        <FolderIcon height={FOLDER_ICON_SIZE} width={FOLDER_ICON_SIZE} />
        <View style={{width}}>
          <Text numberOfLines={1} ellipsizeMode="tail" style={styles.text}>
            {renderText()}
          </Text>
          {showParentName && (
            <View style={styles.bottomTextContainer}>
              <FolderIcon
                height={SMALL_FOLDER_ICON_SIZE}
                width={SMALL_FOLDER_ICON_SIZE}
              />
              <Text style={styles.grayText} numberOfLines={1}>
                {parentName}
              </Text>
            </View>
          )}
        </View>
        {!!unreadDocuments && <RedBubble value={unreadDocuments} />}
      </View>
      <View style={[styles.arrowContainer, styles.marginRight]}>
        <Icon name="keyboardArrowRight" size="lg" />
      </View>
    </TouchableOpacity>
  );
}

export default Folder;
