import React, {useMemo, useState, ReactElement} from 'react';
import {StyleProp, View, ViewStyle} from 'react-native';
import {useTranslation} from 'react-i18next';
import {IconDots} from '@tabler/icons-react-native';
import {Reactions} from '@components/_custom/Reactions';
import {GifPreview} from '@components/_custom/GifPreview';
import {Avatar, IconButton, Pill} from '@components/_HuGo';
import {Typography, Pressable} from '@components/_core';
import {MultimediaContainer} from '@components/_custom/MultimediaContainer';
import TextWithLinks from '@components/TextWithLinks';
import {
  Attachment,
  AttachmentType,
  GifAttachment,
  RequestAttachment,
} from '@interfaces/attachments';
import {BodyAttributes} from '@interfaces/bodyAttributes';
import {Reaction} from '@interfaces/reaction';
import {UserPermissions} from '@interfaces/user';
import {usePermission} from '@redux/selectors';
import {useTheme} from '@shared/theme';
import {getExactTimeAgo} from '@shared/utils/datetime';
import {getCroppedText} from '@shared/utils/texts';
import {BODY_LIMIT} from '@shared/constants';
import {getCompleteName} from '@shared/utils/generics';

import {getPostBodyGifProps} from '../NewPost/utils';
import {styles} from './styles';

export interface CommentItemProps {
  firstName: string;
  lastName: string;
  isExternal?: boolean;
  avatar: Nullable<string>;
  comment: Nullable<string>;
  canReact?: boolean;
  createAt: string;
  onPressLeftIcon?: () => void;
  isReply?: boolean;
  multimediaAttachments?: RequestAttachment[];
  showOptions?: boolean;
  onPressComment?: () => void;
  containerStyle?: StyleProp<ViewStyle>;
  bodyAttributes?: BodyAttributes[];
  onTagPress?: (userId: number) => void;
  onPressUser?: () => void;
  reactions?: Reaction[];
  onToggleReactionsBottomSheet?: () => void;
  onToggleReactionsListDrawer?: (reaction: string) => void;
  onReactionPress?: (reaction: string) => void;
  isArchived?: boolean;
}

export const Comment = React.memo(
  ({
    firstName,
    lastName,
    isExternal,
    avatar,
    comment,
    createAt,
    onPressLeftIcon,
    onPressComment = () => {},
    showOptions,
    multimediaAttachments,
    isReply = false,
    containerStyle,
    bodyAttributes,
    onTagPress,
    onPressUser,
    reactions,
    onToggleReactionsBottomSheet,
    onToggleReactionsListDrawer,
    onReactionPress,
    canReact: canReactProp = false,
    isArchived,
  }: CommentItemProps): ReactElement => {
    const {t} = useTranslation();
    const {theme} = useTheme();
    const canReactGeneral = usePermission(UserPermissions.CAN_REACT_CONTENT);
    const canReact = canReactGeneral || canReactProp;
    const [showText, setShowText] = useState(false);
    const mustCropBody = comment && comment.length >= BODY_LIMIT;
    const onSeeMore = () => setShowText(!showText);
    // TODO: Refactor this to avoid using some(a => a.type === AttachmentType.N)
    const renderMultimedia = useMemo(() => {
      if (multimediaAttachments?.some(a => a.type === AttachmentType.GIF)) {
        return (
          <GifPreview
            gif={multimediaAttachments[0]?.externalReference}
            {...getPostBodyGifProps(
              multimediaAttachments[0] as GifAttachment,
              true,
            )}
          />
        );
      }
      if (multimediaAttachments?.some(a => a.type === AttachmentType.IMAGE)) {
        return (
          <MultimediaContainer
            attachments={multimediaAttachments as Attachment[]}
            withAutoPlay
          />
        );
      }
      if (multimediaAttachments?.some(a => a.type === AttachmentType.VIDEO)) {
        return (
          <MultimediaContainer
            attachments={multimediaAttachments as Attachment[]}
          />
        );
      }
    }, [multimediaAttachments]);

    return (
      <Pressable
        style={[
          styles.container,
          isReply && styles.replyContainer,
          containerStyle,
        ]}
        onPress={onPressComment}>
        <Avatar
          onPress={isExternal ? undefined : onPressUser}
          name={{firstName, lastName}}
          url={avatar}
        />
        <View
          style={[styles.commentContainer, {backgroundColor: theme.neutralBg}]}>
          <View style={styles.commentHeader}>
            <View style={styles.flex}>
              <View
                style={[styles.nameContainer, isExternal && styles.maxWidth]}>
                <Typography
                  onPress={isExternal ? undefined : onPressUser}
                  weight="semiBold"
                  variant="xs"
                  style={styles.name}
                  numberOfLines={1}>
                  {getCompleteName({firstName, lastName})}
                </Typography>
                {isExternal && (
                  <Pill
                    variant="neutral"
                    size="sm"
                    text={t('group.external')}
                  />
                )}
              </View>
              <Typography variant="xxs">{getExactTimeAgo(createAt)}</Typography>
            </View>
            {showOptions && (
              <IconButton
                Icon={IconDots}
                onPress={onPressLeftIcon}
                size="lg"
                variant="tertiary"
                accessibilityLabel={t('general.more_options')}
              />
            )}
          </View>
          <View
            style={[
              styles.bodyTextContainer,
              !canReact && styles.noMarginBottom,
            ]}>
            {comment && (
              <TextWithLinks
                value={
                  mustCropBody
                    ? getCroppedText({body: comment, showing: showText})
                    : comment
                }
                onTagPress={onTagPress}
                attributes={bodyAttributes}
              />
            )}
            {mustCropBody && (
              <Typography
                color={theme.primaryText}
                weight="semiBold"
                variant="xs"
                onPress={onSeeMore}>
                {t(`general.${showText ? 'see_less' : 'see_more'}`)}
              </Typography>
            )}
          </View>
          {renderMultimedia}
          {reactions !== undefined && canReact && (
            <Reactions
              reactions={reactions || []}
              onToggleReactionsBottomSheet={onToggleReactionsBottomSheet}
              onToggleReactionsListDrawer={onToggleReactionsListDrawer}
              onReactionPress={onReactionPress}
              disabled={!!isArchived}
            />
          )}
        </View>
      </Pressable>
    );
  },
);

export * from './components/CommentSkeleton';
