import { motion } from 'framer-motion';
import React, { useState, useEffect, Fragment } from 'react';
import { useSelector } from 'react-redux';
import { isInitialLoaderVisible } from '../../api/storage';
import { BlockClaim } from '../../models/page';
import { RootState } from '../../redux/store';
import styles from './Claim.module.scss';

export type Props = BlockClaim;

const pVariants = {
  hide: {
    transition: {
      staggerChildren: 0.014,
      staggerDirection: 1,
      when: 'afterChildren',
    },
  },
  show: (delay: boolean) => ({
    transition: {
      when: 'beforeChildren',
      staggerChildren: 0.014,
      delayChildren: delay ? 0.85 : 0,
    },
  }),
};

const variants = {
  hide: {
    y: '102%',
  },
  show: {
    y: '0%',
    transition: {
      duration: 0.35,
      ease: [0.09, 0.6, 0, 1],
    },
  },
};

const isCurrentStrongEl = (strongs: ChildNode[], value: string): boolean => {
  const strong = strongs.find(
    (strong, id) =>
      (strong as HTMLElement).innerText === value && strongs?.length - 1 !== id
  );
  return !!strong || false;
};

const Claim = (props: Props): JSX.Element => {
  const { text } = props;
  const { previousRoute, isVisible } = useSelector((state: RootState) => ({
    ...state.router,
    ...state.initialLoader,
  }));
  const isLoaderVisible = !isVisible || !isInitialLoaderVisible();
  const [mounted, setMounted] = useState(false);
  const [phrase, setPhrase] = useState<HTMLElement | null>(null);
  const [delayChildren] = useState(previousRoute !== '' ? true : false);
  const nodes = phrase?.childNodes ? [...phrase?.childNodes] : [];
  let _id = 0;

  const updatePhrase = () => {
    const phrase: HTMLElement | null = process.browser
      ? new DOMParser().parseFromString(text, 'text/html').body
      : null;
    setPhrase(phrase);
  };

  useEffect(() => {
    if (isLoaderVisible) {
      updatePhrase();
      setMounted(true);
    }
  }, [isLoaderVisible]);

  return (
    <div className={styles.claim}>
      <div className={styles.content}>
        {!mounted && <div style={{ opacity: 0 }}>{text}</div>}
        {mounted && (
          <motion.div
            initial="hide"
            animate={'show'}
            variants={pVariants}
            custom={delayChildren}
          >
            {nodes.map((childNode: ChildNode, id) => {
              const childNodes = [...childNode.childNodes];
              const strongs = childNodes.filter(
                (node) => node?.nodeName === 'STRONG'
              );
              const isLastParagraph = id === nodes.length - 1;
              return (
                <p key={id}>
                  {childNodes.map((node, id) => {
                    const isCurrentStrong: boolean = isCurrentStrongEl(
                      strongs,
                      (node as HTMLElement).innerText
                    );
                    const isLastNode = id === childNodes.length - 1;

                    if (isCurrentStrong) _id = _id + 1;
                    return node?.nodeName === 'EM' ? (
                      <em key={id}>
                        {[...(node as HTMLElement).innerHTML.split(' ')].map(
                          (word: string, wordId) => (
                            <span
                              key={`${word}-${wordId}`}
                              className={styles.word}
                            >
                              {[...word].map((letter, letterId) => {
                                _id = _id + 1;
                                if (
                                  isLastParagraph &&
                                  letterId ===
                                    [...(node as HTMLElement).innerHTML]
                                      .length -
                                      1
                                )
                                  _id = _id + 1;
                                return (
                                  <motion.span
                                    variants={variants}
                                    key={_id}
                                    className={
                                      letter === ' ' ? styles.space : ''
                                    }
                                  >
                                    {letter}
                                  </motion.span>
                                );
                              })}
                            </span>
                          )
                        )}
                      </em>
                    ) : node?.nodeName === '#text' ? (
                      [...(node.nodeValue || '').split(' ')].map(
                        (word, wordId) =>
                          word !== '' && (
                            <Fragment key={`${word}-${wordId}`}>
                              <span
                                className={styles.word}
                                key={`${word}-${wordId}`}
                              >
                                {[...word].map((letter, letterId) => {
                                  _id = _id + 1;
                                  return (
                                    <motion.span
                                      variants={variants}
                                      key={_id}
                                      className={
                                        letter === ' ' ? styles.space : ''
                                      }
                                    >
                                      {letter}
                                    </motion.span>
                                  );
                                })}
                                {isLastParagraph &&
                                  isLastNode &&
                                  wordId ===
                                    [...(node.nodeValue || '').split(' ')]
                                      ?.length -
                                      1 && (
                                    <motion.span
                                      variants={variants}
                                      key={`${_id}-dot`}
                                      className={styles.dot}
                                    ></motion.span>
                                  )}
                              </span>
                              {wordId !==
                              [...(node.nodeValue || '').split(' ')]?.length -
                                1 ? (
                                <span
                                  className={styles.space}
                                  key={`${wordId}-space`}
                                >
                                  {' '}
                                </span>
                              ) : null}
                            </Fragment>
                          )
                      )
                    ) : node?.nodeName === 'STRONG' ? (
                      [...(node as HTMLElement).innerHTML.split(' ')].map(
                        (word, wordId) => (
                          <strong key={word}>
                            {[...word].map((letter, letterId) => {
                              _id = _id + 1;

                              return (
                                <motion.span variants={variants} key={_id}>
                                  {letter}
                                </motion.span>
                              );
                            })}
                            {wordId !==
                            [...(node as HTMLElement).innerHTML.split(' ')]
                              .length -
                              1 ? (
                              <motion.span
                                variants={variants}
                                key={_id}
                                className={styles.logo}
                              ></motion.span>
                            ) : null}
                          </strong>
                        )
                      )
                    ) : null;
                  })}
                </p>
              );
            })}
          </motion.div>
        )}
      </div>
    </div>
  );
};
export default Claim;
