import React, { MouseEvent, useRef, useState } from 'react';
import copy_icon from '../../public/imgs/icons/copy_icon.svg';
import styles from './Code.module.scss';
import { LightAsync as SyntaxHighlighter } from 'react-syntax-highlighter';
import codeStyles from './styles';
import {
  motion,
  useAnimation,
  useMotionValue,
  useTransform,
} from 'framer-motion';

export type Props = {
  code: string;
  title: string;
};

const variants = {
  default: {
    height: '342px',
    overflow: 'hidden',
  },
  show: (duration: number) => ({
    height: 'auto',
    overflow: 'hidden',
    transition: {
      duration: duration || 0.3,
    },
  }),
};

const Code = (props: Props): JSX.Element => {
  const { code, title } = props;
  const controls = useAnimation();
  const [isExpanded, setIsExpanded] = useState(false);
  const ref = useRef<HTMLDivElement | null>(null);
  const codeSnippetHeight = useMotionValue(ref?.current?.offsetHeight || 342);
  const duration = useTransform(codeSnippetHeight, [342, 1000], [0.3, 1]);

  const copyCode = (e: MouseEvent<HTMLAnchorElement>) => {
    e.preventDefault();
    navigator.clipboard.writeText(code);
  };

  const onClick = async (): Promise<void> => {
    await controls.start('show');
    setIsExpanded(true);
  };

  return (
    <div className={styles.code}>
      <div className={styles.container}>
        <motion.div
          variants={variants}
          initial="default"
          animate={controls}
          custom={duration.get()}
        >
          <div ref={ref}>
            <SyntaxHighlighter
              language={title}
              style={codeStyles}
              showLineNumbers
            >{`${code}`}</SyntaxHighlighter>
            <div className={styles.copyCodeText}>
              <a
                aria-label="copy code"
                className={`h5 ${styles.h5}`}
                onClick={copyCode}
              >
                Copy Code
                <svg width="16px" height="16px">
                  <use href={copy_icon.src + '#copy_icon'}></use>
                </svg>
              </a>
            </div>
            {!isExpanded ? (
              <>
                <div className={styles.gradient} />
                <button
                  aria-label=""
                  className={styles.btnShowCode}
                  onClick={onClick}
                >
                  Show full code
                </button>
              </>
            ) : null}
          </div>
        </motion.div>
      </div>
    </div>
  );
};

export default Code;
