import { useState, memo } from 'react';

// @ts-ignore TODO: Replace tag-users package since it's not typed and not maintained -> https://www.npmjs.com/package/tag-users
import { getParagraphs } from 'tag-users';
import { SxProps } from '@material-hu/mui/styles';

import Button from '@material-hu/components/design-system/Buttons/Button';
import useHuGoTheme from 'src/hooks/useHuGoTheme';
import { useLokaliseTranslation } from 'src/utils/i18n';
import {
  countNumberOfCharacters,
  linesCounter,
} from 'src/utils/manageTextLength';
import ParagraphsTextType from 'src/components/post/ParagraphsTextType';

export type PostTextProps = {
  body: string;
  bodyAttributes: any;
  maxCharacters: number;
  maxNewLines: number;
  enableSeeMore?: boolean;
  showSeeMoreToggle?: boolean;
  defaultReadMore?: boolean;
  matchText?: string;
  onReadMore?: Function;
  onReadLess?: Function;
};

const buttonStyles: SxProps = {
  minWidth: 'fit-content',
  '&:hover': { background: 'transparent' },
};

const PostText = ({
  body,
  maxCharacters,
  maxNewLines,
  bodyAttributes,
  enableSeeMore = true,
  showSeeMoreToggle = false,
  defaultReadMore = false,
  matchText = '',
  onReadMore = () => null,
  onReadLess = () => null,
}: PostTextProps) => {
  const { t } = useLokaliseTranslation();
  const HugoThemeProvider = useHuGoTheme();
  const [readMore, setReadMore] = useState(defaultReadMore);

  const handleReadMore = () => {
    setReadMore(true);
    onReadMore();
  };

  const handleReadLess = () => {
    setReadMore(false);
    onReadLess();
  };

  const newLinesCounter = linesCounter(body);
  const isTextLimited = body.length > maxCharacters;

  if (body) {
    return (
      <>
        {getParagraphs(body, bodyAttributes).map(
          (paragraph: any, index: number, row: any) => {
            const multiLinesAndTag = row.length > 1;
            let hasToBeRead = true;
            let split = false;
            let count = 0;
            let preCount = 0;

            if (!readMore && multiLinesAndTag) {
              const slicedNewArray = row.slice(0, index + 1);
              const slicedPreArray = row.slice(0, index);
              count = countNumberOfCharacters(slicedNewArray);
              preCount = countNumberOfCharacters(slicedPreArray);
            }

            const isNewLineLimited = multiLinesAndTag
              ? row.length > maxNewLines
              : newLinesCounter > maxNewLines;

            const remainingCharacters = maxCharacters - preCount;
            const remainingNewLines = maxNewLines - index;

            if (multiLinesAndTag) {
              if (!readMore) {
                hasToBeRead = remainingCharacters > 0 && remainingNewLines >= 0;
                if (count - preCount >= remainingCharacters) {
                  split = true;
                }
              }
            } else if (isTextLimited || isNewLineLimited) {
              split = true;
            }

            const showToggle =
              enableSeeMore &&
              (isTextLimited || isNewLineLimited || showSeeMoreToggle);
            const showLess = !multiLinesAndTag || index === row.length - 1;
            const showMore =
              !multiLinesAndTag || remainingNewLines === 0 || split;

            if (readMore || hasToBeRead) {
              return (
                <div
                  key={index}
                  style={{
                    flexDirection: 'row',
                    flexWrap: 'wrap',
                    wordBreak: 'break-word',
                  }}
                >
                  <ParagraphsTextType
                    paragraph={paragraph}
                    hasToBeSplit={!readMore && split}
                    maxCharacters={remainingCharacters}
                    maxNewLines={remainingNewLines}
                    matchText={matchText}
                  />
                  {!enableSeeMore &&
                    (isTextLimited || isNewLineLimited) &&
                    '...'}
                  {showToggle && readMore && showLess && (
                    <Button
                      sx={buttonStyles}
                      variant="text"
                      onClick={handleReadLess}
                    >
                      {t('SEE_LESS')}
                    </Button>
                  )}
                  {showToggle && !readMore && showMore && (
                    <Button
                      sx={buttonStyles}
                      variant="text"
                      onClick={handleReadMore}
                    >
                      {t('SEE_MORE')}
                    </Button>
                  )}
                </div>
              );
            }

            return null;
          },
        )}
      </>
    );
  }

  return (
    <HugoThemeProvider>
      {enableSeeMore && showSeeMoreToggle && readMore && (
        <Button
          sx={buttonStyles}
          variant="text"
          onClick={handleReadLess}
        >
          {t('SEE_LESS')}
        </Button>
      )}
      {enableSeeMore && showSeeMoreToggle && !readMore && (
        <Button
          sx={buttonStyles}
          variant="text"
          onClick={handleReadMore}
        >
          {t('SEE_MORE')}
        </Button>
      )}
    </HugoThemeProvider>
  );
};

export default memo(PostText);
