import React from 'react'
import ReactDOM from 'react-dom';
import { LiveEditor, LiveProvider, LivePreview, LiveError } from 'react-live';
import { PrismTheme } from 'prism-react-renderer';
import Components from '../../exports';
import { css } from '@emotion/css';

type Props = {
    codeText: string
    scope?: {}
    isOpenByDefault?: boolean
    noInline?: boolean
}

type State = {
    uniqueId: string
    isCodeCollapsed: boolean
    hasError: boolean
    codeText: string
}

const editorTheme: PrismTheme = {
    plain: {
        fontSize: '14px'
    },
    styles: []
}

// until
// https://reactjs.org/docs/hooks-faq.html#do-hooks-cover-all-use-cases-for-classes
// is implemented this has to be a class component
class Playground extends React.Component<Props, State> {
    static defaultProps = {
        noInline: false,
        isOpenByDefault: true
    }

    constructor(props: Props) {
        super(props);

        this.state = {
            uniqueId: "asd",
            isCodeCollapsed: !props.isOpenByDefault,
            hasError: false,
            codeText: props.codeText
        }
    }

    componentDidCatch() {
        // Display fallback UI
        this.setState({ hasError: true })
    }

    handleToggle = () => {
        this.setState(({ isCodeCollapsed }) => ({
            isCodeCollapsed: !isCodeCollapsed
        }))
    }

    renderError = () => {
        return (
            <div className="Playground-error">
                <p>
                    Oops, something went wrong in with this live preview.
          <br /> Please reload the page and try again.
        </p>
            </div>
        )
    }

    handleChange = (codeText: string) => {
        this.setState({
            codeText
        })
    }

    render() {
        const { scope, noInline } = this.props
        const { codeText, hasError, isCodeCollapsed, uniqueId } = this.state

        if (hasError) return this.renderError()

        return (
            <LiveProvider
                theme={editorTheme}
                scope={{ ReactDOM, ...Components, ...scope }}
                code={codeText}
                noInline={noInline}
            >
                <div
                    data-iscodecollapsed={isCodeCollapsed}
                    className={css({
                        backgroundColor: '#f9f9fb',
                        borderRadius: 5,
                        overflow: 'hidden',
                        marginTop: 24,
                        "&[data-iscodecollapsed='false']": {
                            backgroundColor: '#234361'
                        }
                    })}
                >
                    <div>
                        <LiveError />
                        
                        <div
                            className={css({
                                backgroundColor: '#FFF',
                                color: '#66788a',
                                margin: 4,
                                padding: 16,
                                boxShadow: '0 0 0 1px rgba(67,90,111,.14)'
                            })}
                        >
                            <LivePreview />
                        </div>
                        {!isCodeCollapsed && (
                            <div>
                                <LiveEditor
                                    className="prism-code"
                                    onChange={this.handleChange}
                                    disabled
                                />
                            </div>
                        )}
                    </div>
                    <div
                        aria-expanded={!isCodeCollapsed}
                        role="button"
                        aria-controls={`code-playground-${uniqueId}`}
                        onClick={this.handleToggle}
                        className={css({
                            cursor: 'pointer',
                            userSelect: 'none',
                            position: 'relative',
                            padding: 8,
                            fontSize: 14,
                            textTransform: 'uppercase',
                            display: 'flex',
                            alignItems: 'center',
                            justifyContent: 'center',
                            fontFamily: 'SF Mono,Monaco,Inconsolata,Fira Mono,Droid Sans Mono,Source Code Pro,monospace',
                            color: isCodeCollapsed ? 'inherit' : '#FFFFFF'
                        })}
                    >
                        {isCodeCollapsed ? 'Show code' : 'Hide code'}
                    </div>
                   
                </div>
            </LiveProvider>
        )
    }
}

export default Playground