import React, {useLayoutEffect, useRef} from 'react';
import PropTypes from 'prop-types';
import {CopyToClipboard} from 'react-copy-to-clipboard';
import * as Prism from 'prismjs';
import {showTooltip, hideTooltip, TOOLTIP_POSITION} from '@propellerads/smart-tooltip';
import {SIZE, Copy} from '@propellerads/icon';

import {StyledCodeviewer, CodeviewerCopyButton, CommonCodeViewerStyles} from './style';

const CodeViewer = (props) => {
  const {
    copyingEnabled,
    children,
    language,
    elementId,
    tipCodeCopied,
    highlightCode,
  } = props;

  const codeViewer = useRef(null);

  useLayoutEffect(() => {
    if (highlightCode && codeViewer.current) {
      Prism.highlightElement(codeViewer.current);
    }
  }, [highlightCode]);

  const CopyButton = (
    <CodeviewerCopyButton
      id={`${elementId}-copy-button`}
      type="button"
      onMouseDown={(e) => showTooltip(e.target, tipCodeCopied, TOOLTIP_POSITION.TOP)}
      onMouseLeave={() => hideTooltip()}
    >
      <Copy size={SIZE.MEDIUM_SMALL} />
    </CodeviewerCopyButton>
  );

  return (
    <StyledCodeviewer id={elementId}>
      <CommonCodeViewerStyles />
      {highlightCode ? (
        <pre key="code-viewer-with-highlight">
          <code
            className={`lang-${language}`}
            ref={codeViewer}
          >
            {children}
          </code>
        </pre>
      ) : (
        <pre className="language-none" key="code-viewer-without-highlight">
          <code className="language-none">{children}</code>
        </pre>
      )}

      {copyingEnabled && (
        <CopyToClipboard text={children}>
          {CopyButton}
        </CopyToClipboard>
      )}
    </StyledCodeviewer>
  );
};

CodeViewer.propTypes = {
  children: PropTypes.oneOfType([PropTypes.element, PropTypes.string, PropTypes.node]),
  language: PropTypes.string,
  copyingEnabled: PropTypes.bool,
  elementId: PropTypes.string.isRequired,
  tipCodeCopied: PropTypes.oneOfType([PropTypes.element, PropTypes.string]),
  highlightCode: PropTypes.bool,
};

CodeViewer.defaultProps = {
  children: null,
  language: 'markup',
  copyingEnabled: true,
  tipCodeCopied: 'Copied!',
  highlightCode: true,
};

export default CodeViewer;
