import React, {useState} from 'react';
import {View, StyleProp, ViewStyle} from 'react-native';
import {useTranslation} from 'react-i18next';
import {Typography, TypographyProps, HtmlRender} from '@components';
import {BODY_LIMIT} from '@shared/constants';
import {useTheme} from '@shared/theme';
import {
  getCroppedText,
  getCroppedHtml,
  shouldCropHtml,
} from '@shared/utils/texts';
import {getHtmlToRender} from '@shared/utils';

import {styles} from './styles';

export interface CroppedBodyProps extends TypographyProps {
  body: string;
  isHtml?: boolean;
  textStyle?: object;
  showMoreStyle?: object;
  bodyLimit?: number;
  containerStyle?: StyleProp<ViewStyle>;
  alignLeft?: boolean;
  onPressSeeMore?: () => void;
}

export function CroppedBody({
  body,
  isHtml = false,
  textStyle,
  showMoreStyle,
  bodyLimit = BODY_LIMIT,
  containerStyle,
  alignLeft,
  onPressSeeMore,
  ...props
}: CroppedBodyProps) {
  const {t} = useTranslation();
  const {theme} = useTheme();
  const [textShown, setTextShown] = useState(false);

  const mustCropBody = isHtml
    ? shouldCropHtml(body, bodyLimit)
    : body?.length >= bodyLimit;

  const onSeeMore = () => {
    onPressSeeMore?.();
    setTextShown(!textShown);
  };

  const croppedHtml = isHtml
    ? getCroppedHtml({html: body, showing: textShown, limit: bodyLimit})
    : '';

  return (
    <View style={[styles.bodyTextContainer, containerStyle]}>
      {isHtml ? (
        <HtmlRender
          html={getHtmlToRender(croppedHtml)}
          textStyle={[styles.bodyText, textStyle]}
        />
      ) : (
        <Typography style={[styles.bodyText, textStyle]} variant="s" {...props}>
          {getCroppedText({body, showing: textShown, limit: bodyLimit})}
        </Typography>
      )}
      {mustCropBody && (
        <Typography
          weight="semiBold"
          variant="xs"
          style={[
            styles.showMore,
            showMoreStyle,
            alignLeft && styles.showMoreLeft,
          ]}
          color={theme.primaryText}
          onPress={onSeeMore}>
          {t(`general.${textShown ? 'see_less' : 'see_more'}`)}
        </Typography>
      )}
    </View>
  );
}
