import React, { useEffect, useState, useRef } from "react";
import clsx from "clsx";
import Highlight, { defaultProps } from "prism-react-renderer";
import copy from "copy-text-to-clipboard";
import {useColorMode} from '@docusaurus/theme-common';
import Translate, { translate } from "@docusaurus/Translate";
import Link from "@docusaurus/Link";

import monokai from "@site/src/plugins/prism_themes/monokai";
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";

import styles from "./styles.module.css";

function SampleSnippet(props) {
  const {
    siteConfig: {
      themeConfig: { prism = {} },
    },
  } = useDocusaurusContext();

  const [showCopied, setShowCopied] = useState(false);
  const [mounted, setMounted] = useState(false);
  // The Prism theme on SSR is always the default theme but the site theme
  // can be in a different mode. React hydration doesn't update DOM styles
  // that come from SSR. Hence force a re-render after mounting to apply the
  // current relevant styles. There will be a flash seen of the original
  // styles seen using this current approach but that's probably ok. Fixing
  // the flash will require changing the theming approach and is not worth it
  // at this point.
  useEffect(() => {
    setMounted(true);
  }, []);

  const {isDarkTheme} = useColorMode();;
  const lightModeTheme = prism.theme || monokai;
  const darkModeTheme = prism.darkTheme || lightModeTheme;
  const prismTheme = isDarkTheme ? darkModeTheme : lightModeTheme;

  const button = useRef(null);

  const { lang = "python", config, copyBit, further } = props;

  let copySnippet = copyBit || config;
  const handleCopyCode = () => {
    copy(copySnippet);
    setShowCopied(true);

    setTimeout(() => setShowCopied(false), 2000);
  };

  return (
    <Highlight
      {...defaultProps}
      key={mounted}
      theme={prismTheme}
      code={config}
      language={lang}
    >
      {({ className, style, tokens, getLineProps, getTokenProps }) => (
        <div className={styles.codeBlockContainer}>
          <div className={clsx(styles.codeBlockContent, lang)}>
            <pre className={`${className}`} style={style}>
              {tokens.map((line, i) => (
                <div {...getLineProps({ line, key: i })}>
                  {line.map((token, key) => (
                    <span {...getTokenProps({ token, key })} />
                  ))}
                </div>
              ))}
            </pre>

            <button
              ref={button}
              type="button"
              aria-label={translate({
                id: "theme.CodeBlock.copyButtonAriaLabel",
                message: "Copy code to clipboard",
                description: "The ARIA label for copy code blocks button",
              })}
              className={clsx(styles.copyButton, "clean-btn")}
              onClick={handleCopyCode}
            >
              {showCopied ? (
                <Translate
                  id="theme.CodeBlock.copied"
                  description="The copied button label on code blocks"
                >
                  Copied
                </Translate>
              ) : (
                <Translate
                  id="theme.CodeBlock.copy"
                  description="The copy button label on code blocks"
                >
                  Copy
                </Translate>
              )}
            </button>

            {further && (
              <Link
                className={clsx(
                  styles.furtherButton,
                  "button button--outline button--primary"
                )}
                to={further}
              >
                Read more
              </Link>
            )}
          </div>
        </div>
      )}
    </Highlight>
  );
}

export default SampleSnippet;
