import React, {useMemo, useState} from 'react';
import {Pressable, View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {StackActions, useNavigation} from '@react-navigation/native';
import {
  Typography,
  BasePost,
  HtmlRender,
  TypographyWithLinks,
} from '@components';
import {useTheme} from '@shared/theme';
import {Screens} from '@shared/constants';
import {copyToClipboard, getHtmlToRender, truncateHtml} from '@shared/utils';

import {styles} from './styles';

const POST_BODY_LIMIT = 300;

interface PostBodyProps {
  onPressBody?: () => void;
  post: BasePost;
  truncate: boolean;
}

export function PostBody({
  onPressBody,
  post: {body, bodyAttributes, bodyHtml},
  truncate,
}: PostBodyProps) {
  const navigation = useNavigation();
  const {t} = useTranslation();
  const {theme} = useTheme();
  const [textShown, setTextShown] = useState(false);
  const hasLongBody = body.length >= POST_BODY_LIMIT;
  const truncatedHtml = useMemo(
    () => truncateHtml(bodyHtml, POST_BODY_LIMIT, 4),
    [bodyHtml],
  );

  const croppedBody = useMemo(() => {
    if (!body) {
      return '';
    }
    if (textShown || !hasLongBody) {
      return body;
    }
    const shortenedBody = body.slice(0, POST_BODY_LIMIT);
    const lastIndex = shortenedBody.lastIndexOf(' ');
    return shortenedBody.substring(0, lastIndex);
  }, [body, hasLongBody, textShown]);

  const onToggleShown = () => {
    setTextShown(prevState => !prevState);
  };

  const onTagPress = (taggedUserId: number) => {
    navigation.dispatch(
      StackActions.push(Screens.PROFILE, {userId: taggedUserId}),
    );
  };

  const onLongPress = () => {
    copyToClipboard({text: croppedBody});
  };

  const html = useMemo(
    () =>
      bodyHtml
        ? getHtmlToRender(
            textShown || !truncate ? bodyHtml : truncatedHtml.htmlTruncated,
          )
        : '',
    [bodyHtml, textShown, truncatedHtml.htmlTruncated, truncate],
  );

  return (
    <Pressable
      onPress={onPressBody}
      onLongPress={onLongPress}
      style={styles.container}>
      <View style={styles.bodyTextContainer}>
        {bodyHtml ? (
          <HtmlRender html={html} />
        ) : (
          <TypographyWithLinks
            value={croppedBody}
            attributes={bodyAttributes}
            onTagPress={onTagPress}
          />
        )}
      </View>
      {(bodyHtml ? truncate && truncatedHtml.isTruncated : hasLongBody) && (
        <View style={styles.seeMoreContainer}>
          <Typography
            color={theme.text.neutral.brand}
            onPress={onToggleShown}
            variant="xs"
            weight="semiBold">
            {t(textShown ? 'general.see_less' : 'general.see_more')}
          </Typography>
        </View>
      )}
    </Pressable>
  );
}
