import React, { Component } from 'react';
import styled from '@emotion/styled';
import { document, window } from 'global';
import memoize from 'memoizerific';
import jsx from 'react-syntax-highlighter/languages/prism/jsx';
import bash from 'react-syntax-highlighter/languages/prism/bash';
import SyntaxHighlighter, { registerLanguage } from 'react-syntax-highlighter/prism-light';
import prettier from 'prettier/standalone';
import parser from 'prettier/parser-babylon';
import { ActionBar, ActionButton } from '../panel_actionbar/panel_actionbar';

registerLanguage('jsx', jsx);
registerLanguage('bash', bash);

const themedSyntax = memoize(2)(theme =>
  Object.entries(theme.code).reduce((acc, [key, val]) => ({ ...acc, [`* .${key}`]: val }), {})
);

const Wrapper = styled.div(
  {
    position: 'relative',
    overflow: 'hidden',
  },
  ({ theme, bordered }) =>
    bordered
      ? {
          border: theme.mainBorder,
          borderRadius: theme.mainBorderRadius,
          background: theme.barFill,
        }
      : {}
);
const Scroller = styled.div(
  {
    position: 'relative',
    overflow: 'auto',
  },
  ({ theme }) => ({
    '& code': {
      paddingRight: theme.layoutMargin,
      opacity: 0.7,
    },
  }),
  ({ theme }) => themedSyntax(theme)
);
const Pre = styled.pre(({ theme, padded }) => ({
  display: 'flex',
  justifyContent: 'flex-start',
  margin: 0,
  padding: padded ? theme.layoutMargin : 0,
}));
const Code = styled.code({
  flex: 1,
  paddingRight: 0,
  opacity: 1,
});

export default class Copyable extends Component {
  state = { copied: false };

  constructor(props) {
    super(props);

    const { language, children } = props;
    let formattedCode = children.trim();
    if (language === 'jsx') {
      formattedCode = prettier.format(formattedCode, {
        parser: 'babylon',
        plugins: [parser],
      });
    }
    this.state = { formattedCode };
  }

  onClick = e => {
    const { children } = this.props;

    e.preventDefault();
    const tmp = document.createElement('TEXTAREA');
    const focus = document.activeElement;

    tmp.value = children;

    document.body.appendChild(tmp);
    tmp.select();
    document.execCommand('copy');
    document.body.removeChild(tmp);
    focus.focus();

    this.setState({ copied: true }, () => {
      window.setTimeout(() => this.setState({ copied: false }), 1500);
    });
  };

  render() {
    const { children, language = 'jsx', copyable = true, bordered, padded, ...rest } = this.props;
    const { copied, formattedCode } = this.state;

    return children ? (
      <Wrapper bordered={bordered} padded={padded}>
        <Scroller>
          <SyntaxHighlighter
            padded={padded || bordered}
            language={language}
            useInlineStyles={false}
            PreTag={Pre}
            CodeTag={Code}
            lineNumberContainerStyle={{}}
            {...rest}
          >
            {formattedCode}
          </SyntaxHighlighter>
        </Scroller>
        {copyable ? (
          <ActionBar>
            <ActionButton onClick={this.onClick}>{copied ? 'copied' : 'copy'}</ActionButton>
          </ActionBar>
        ) : null}
      </Wrapper>
    ) : null;
  }
}

@@ -1587,89 +1587,53 @@
 %0A%0A  
-constructor(props) %7B%0A    super(props);%0A%0A    const %7B language, children %7D = props;
+formatCode = memoize(2)((language, code) =%3E %7B
 %0A   
@@ -1658,22 +1658,11 @@
  = c
-hildren.trim()
+ode
 ;%0A  
@@ -1685,24 +1685,38 @@
 == 'jsx') %7B%0A
+      try %7B%0A  
       format
@@ -1745,25 +1745,18 @@
 mat(
-formattedC
+c
 ode, %7B%0A
+  
     
@@ -1786,16 +1786,18 @@
         
+  
 plugins:
@@ -1807,16 +1807,18 @@
 arser%5D,%0A
+  
       %7D)
@@ -1827,28 +1827,147 @@
     
-%7D%0A    this.state = %7B
+  %7D catch (error) %7B%0A        console.warn(%22Couldn't format code%22, formattedCode); // eslint-disable-line no-console%0A      %7D%0A    %7D%0A    return
  for
@@ -1980,15 +1980,15 @@
 Code
- %7D
 ;%0A  %7D
+);
 %0A%0A  
@@ -2591,31 +2591,16 @@
 %7B copied
-, formattedCode
  %7D = thi
@@ -2982,29 +2982,58 @@
        %7B
+this.
 format
-ted
 Code
+(language, children.trim())
 %7D%0A      

Fix issue with previous commit