import React, {useEffect, useMemo, useState} from 'react';
import {
  View,
  TouchableOpacity,
  TouchableOpacityProps,
  StyleProp,
  ViewStyle,
  TextStyle,
} from 'react-native';
import {useTranslation} from 'react-i18next';
import {useNavigation} from '@react-navigation/native';
import Signature from '@assets/signature.svg';
import FolderIcon from '@assets/folder.svg';
import Icon from '@components/Icon';
import Text from '@components/Text';
import ActivityIndicator from '@components/ActivityIndicator';
import useGetMeasurements from '@hooks/useGetMeasurements';
import {COLORS} from '@shared/colors';
import {SHARED_STRINGS} from '@shared/strings';
import {Opacity, FILE_TYPES, Screens} from '@shared/constants';
import {
  getFileNameExtension,
  getFileNameFromUrl,
  getFullDate,
  shortenText,
  selectSvgLogo,
} from '@shared/utils';
import {commonStyles} from '@shared/styles';

import {FileAndAttachment, SignatureStatus} from '../../interfaces';
import {getComponentsBySearchTerm} from '../../utils';
import {
  NAME_LIMIT,
  FILE_ICON_SIZE,
  BOTTOM_LOGO_SIZE,
  SMALL_FOLDER_ICON_SIZE,
} from '../../constants';
import {styles, getContainerTextWidthDifference, EXTRA_HEIGHT} from './styles';
import {SIGNATURE_TEXT} from './strings';

interface Props extends Pick<TouchableOpacityProps, 'onPress' | 'onLongPress'> {
  item: FileAndAttachment;
  searchTerm?: string;
  showSubtitle?: boolean;
  getSubtitle?: (val: {folderId: number}) => string;
  containerStyle?: StyleProp<ViewStyle>;
  textStyle?: StyleProp<TextStyle>;
  loading?: boolean;
  showParentName?: boolean;
  withPreview?: boolean;
}

function File({
  item,
  searchTerm,
  showSubtitle,
  getSubtitle,
  onPress,
  onLongPress,
  containerStyle,
  textStyle,
  loading,
  showParentName,
  withPreview,
}: Props) {
  const navigation = useNavigation();
  const [onLayout, measurements] = useGetMeasurements();
  const [folderAndNameWidth, setFolderAndNameWidth] = useState<number>();

  useEffect(() => {
    !folderAndNameWidth && setFolderAndNameWidth(measurements.width);
  }, [measurements.width, setFolderAndNameWidth, folderAndNameWidth]);
  const {
    name,
    size,
    folderId,
    parentName,
    signatureDate,
    signatureStatus,
    canBeSigned,
    url,
    source,
  } = item;
  const {t} = useTranslation();
  const completeName = name || getFileNameFromUrl(source || url);
  const extension = getFileNameExtension(completeName, true);
  const isPending = signatureStatus === SignatureStatus.PENDING;
  const hasSignature = useMemo(
    () =>
      [
        SignatureStatus.SIGNED,
        SignatureStatus.SIGNED_IN_AGREEMENT,
        SignatureStatus.SIGNED_IN_DISAGREEMENT,
      ].includes(signatureStatus),
    [signatureStatus],
  );
  const fileName = useMemo(
    () => shortenText(completeName, NAME_LIMIT),
    [completeName],
  );
  const indexOfSearchTerm = useMemo(
    () =>
      searchTerm && fileName.toLowerCase().indexOf(searchTerm.toLowerCase()),
    [fileName, searchTerm],
  );

  const renderText = () =>
    searchTerm &&
    typeof indexOfSearchTerm === 'number' &&
    indexOfSearchTerm >= 0
      ? getComponentsBySearchTerm(fileName, indexOfSearchTerm, searchTerm).map(
          ({text, bold}, index) => (
            <Text key={index} weight={bold ? 'bold' : 'regular'}>
              {text}
            </Text>
          ),
        )
      : fileName;

  const containerWidthDifference = useMemo(
    () => getContainerTextWidthDifference(isPending),
    [isPending],
  );

  const onPreviewFile = () => {
    navigation.navigate(Screens.CSV_PREVIEWER, item);
  };

  return (
    <TouchableOpacity
      onPress={onPress}
      onLongPress={onLongPress}
      onLayout={onLayout}
      style={[
        styles.itemContainer,
        (hasSignature || showParentName) && {height: EXTRA_HEIGHT},
        containerStyle,
      ]}>
      <View style={styles.folderAndName}>
        <View style={styles.logoContainer}>
          {selectSvgLogo(extension, FILE_ICON_SIZE)}
        </View>
        <View>
          {!!folderAndNameWidth && !!containerWidthDifference && (
            <View
              style={{
                width: folderAndNameWidth - containerWidthDifference,
              }}>
              <Text
                variant="m"
                numberOfLines={1}
                ellipsizeMode="tail"
                style={[styles.text, textStyle]}>
                {renderText()}
              </Text>
              {showSubtitle && (
                <Text
                  variant="body2"
                  color={COLORS.DARK_GRAY}
                  style={textStyle}>
                  {getSubtitle?.({folderId}) || `${extension} - ${size}`}
                </Text>
              )}
            </View>
          )}
          {hasSignature && (
            <View style={styles.bottomTextContainer}>
              <Signature
                width={BOTTOM_LOGO_SIZE}
                height={BOTTOM_LOGO_SIZE}
                style={styles.signatureLogo}
              />
              <Text numberOfLines={2} style={commonStyles.flex}>
                <Text weight="bold" style={styles.grayText}>
                  {`${t(SIGNATURE_TEXT[signatureStatus])} `}
                </Text>
                {signatureDate && (
                  <Text style={styles.grayText}>
                    {getFullDate(signatureDate)}
                  </Text>
                )}
              </Text>
            </View>
          )}
          {showParentName && (
            <View style={styles.bottomTextContainer}>
              <FolderIcon
                width={SMALL_FOLDER_ICON_SIZE}
                height={SMALL_FOLDER_ICON_SIZE}
                style={styles.folderIcon}
              />
              <Text style={styles.grayText} numberOfLines={1}>
                {parentName}
              </Text>
            </View>
          )}
        </View>
      </View>
      {isPending && !loading && (
        <TouchableOpacity
          onPress={onPress}
          activeOpacity={Opacity.MEDIUM}
          style={[
            styles.signButtonContainer,
            {
              backgroundColor: canBeSigned ? COLORS.BLACK : COLORS.GRAY_TWENTY,
            },
          ]}>
          <Text color={COLORS.WHITE}>{t(SHARED_STRINGS.SIGN)}</Text>
        </TouchableOpacity>
      )}
      {withPreview && extension === FILE_TYPES.CSV && (
        <TouchableOpacity
          onPress={onPreviewFile}
          style={styles.filterIconContainer}>
          <Icon name="filterAltFill" color="white" />
        </TouchableOpacity>
      )}
      <ActivityIndicator isVisible={loading} />
    </TouchableOpacity>
  );
}

export default File;
