import * as React from 'react'
import * as PropTypes from 'prop-types'
import PrismTheme from '../../utilities/prism-themes/dark'
import {
  LiveProvider,
  LiveEditor,
  LivePreview
} from 'react-live'
import styled from 'styled-components'

const Figure = styled('figure')({
  display: 'block',
  margin: '0 -1rem',
  padding: '1rem',
  boxSizing: 'border-box',
  position: 'relative',
  '@media only screen': {
    '::before': {
      position: 'absolute',
      content: "''",
      zIndex: -1,
      backgroundColor: 'var(--color-shade)',
      opacity: 0.125,
      top: 0,
      left: 0,
      width: '100%',
      height: '100%',
    }
  },
})

const PlaygroundCaption = styled('span')({
  display: 'none',
  '@media only screen': {
    display: 'inline',
  },
})

const Caption = styled('figcaption')({
  fontSize: '0.75rem',
  fontWeight: 'bolder',
  textTransform: 'uppercase',
  marginBottom: '1rem',
  marginTop: '-0.5rem',
})

const CaptionPrint = styled(Caption)({
  display: 'none',
  '@media only screen': {
    display: 'block',
  },
})

const StyledLiveEditor = styled(LiveEditor)({
  lineHeight: 1.125,
  fontFamily: 'var(--font-family-monospace), monospace !important',
  marginTop: '1rem',
  'textarea': {
    padding: '0 !important',
    outline: 0,
  },
  'pre': {
    padding: '0 !important',
  },
})

const propTypes = {
  components: PropTypes.object,
  code: PropTypes.string.isRequired,
  label: PropTypes.string,
}

type Props = PropTypes.InferProps<typeof propTypes>

const Playground: React.FC<Props> = ({
  components,
  code,
  label,
}) => {
  const [enabled, setEnabled, ] = React.useState(false)
  const indentLevel = code.indexOf('<') - 1
  const normalizedCode = code
    .split('\n')
    .map((s: string) => s.slice(indentLevel))
    .filter((s: string) => s.trim().length > 0)
    .join('\n')

  React.useEffect(() => {
    setEnabled(true)
  }, [])

  return (
    <Figure>
      {
        label as string
        && (
          <Caption>
            <PlaygroundCaption>
              {'Playground - '}
            </PlaygroundCaption>
            {label}
          </Caption>
        )
      }
      {
        !label
        && enabled
        && (
          <CaptionPrint>
            Playground
          </CaptionPrint>
        )
      }
      <div>
        <LiveProvider
          code={normalizedCode}
          scope={{
            ...components,
          }}
        >
          <LivePreview />
          {
            enabled
            && (
              <StyledLiveEditor
                theme={PrismTheme}
              />
            )
          }
        </LiveProvider>
      </div>
    </Figure>
  )
}

Playground.propTypes = propTypes

export default Playground
