import React, {useCallback} from 'react'
import PropTypes from 'prop-types'
import hoistNonReactStatics from 'hoist-non-react-statics'
import Button from 'react-uikit/button'
import Form from 'react-uikit/form'
import TextInput from 'react-uikit/input-text'
import Editor from 'components/editor'
import ToolbarItem, {
    TOOLBAR_ITEM_KEYS,
} from 'components/editor/partials/toolbar-item'
import inputNames from 'common-fe/constants/input-names'
import {uuid} from 'common-fe/utils'
import BEMModule from 'utils/bem'
import styles from './styles.scss'

const bem = new BEMModule(styles)

const PostForm = React.forwardRef((props, ref) => {
    const {data, post, onCancel, onChange, onSubmit} = props
    const formName = post?.id ? `edit-post-${post.id}` : PostForm.formName
    // Need to handle ref in order to give connect-form a state to initialize
    // our form with in the store.
    if (ref) {
        ref.current = {
            formName,
            initialState: {
                data: {
                    [inputNames.TITLE]: post?.title || data[inputNames.TITLE],
                    [inputNames.BODY]: post?.body || data[inputNames.BODY],
                },
            },
        }
    }

    const classes = bem.classNames('c-post-form')
    const labelClasses = bem.classNames('c-post-form__label')
    const bodyClasses = bem.classNames('c-post-form__body')
    const actionsClasses = bem.classNames('c-post-form__actions')
    const cancelClasses = bem.classNames('c-post-form__actions__cancel')
    const bodyId = `post-form-body__${post?.id || uuid()}`

    const change = useCallback(({name, value}) => onChange?.({[name]: value}), [
        onChange,
    ])

    const submit = useCallback(
        ({[inputNames.TITLE]: title, [inputNames.BODY]: body}) =>
            onSubmit?.({
                title,
                body: JSON.stringify(body),
            }),
        [onChange, onSubmit]
    )

    return (
        <Form
            className={classes}
            data={data}
            name={formName}
            submitOnEnter={false}
            onChange={change}
            onSubmit={submit}
        >
            <Form.Field
                label="Title"
                name={inputNames.TITLE}
                size="small"
                render={TextInput}
                required
            />

            <TextInput.Label
                className={labelClasses}
                label="Body"
                htmlFor={bodyId}
            />

            <Form.Field
                id={bodyId}
                className={bodyClasses}
                name={inputNames.BODY}
                placeholder="Write a message..."
                toolbar={[
                    <ToolbarItem
                        key={Editor.marks.BOLD}
                        iconName={TOOLBAR_ITEM_KEYS.BOLD}
                        mark={Editor.marks.BOLD}
                    />,
                    <ToolbarItem
                        key={Editor.marks.ITALIC}
                        iconName={TOOLBAR_ITEM_KEYS.ITALIC}
                        mark={Editor.marks.ITALIC}
                    />,
                    <ToolbarItem
                        key={Editor.marks.UNDERLINE}
                        iconName={TOOLBAR_ITEM_KEYS.UNDERLINE}
                        mark={Editor.marks.UNDERLINE}
                    />,
                    <ToolbarItem
                        key={Editor.blocks.H1}
                        iconName={TOOLBAR_ITEM_KEYS.H1}
                        block={Editor.blocks.H1}
                    />,
                    <ToolbarItem
                        key={Editor.blocks.VIDEO}
                        iconName={TOOLBAR_ITEM_KEYS.VIDEO}
                        block={Editor.blocks.VIDEO}
                    />,
                    <ToolbarItem
                        key={Editor.blocks.IMAGE}
                        iconName={TOOLBAR_ITEM_KEYS.IMAGE}
                        block={Editor.blocks.IMAGE}
                    />,
                ]}
                render={Editor}
            />

            <div className={actionsClasses}>
                <Button
                    className={cancelClasses}
                    constrained
                    size="small"
                    text="Cancel"
                    onClick={onCancel}
                />
                <Form.SubmitTrigger
                    constrained
                    variant="primary"
                    size="small"
                    text={post ? 'Save Post' : 'Post Message'}
                    render={Button}
                />
            </div>
        </Form>
    )
})

PostForm.displayName = 'PostForm'
PostForm.formName = 'post-form'

PostForm.defaultProps = {
    data: {
        [inputNames.TITLE]: '',
        [inputNames.BODY]: null,
    },
}

PostForm.propTypes = {
    data: PropTypes.shape({
        [inputNames.BODY]: PropTypes.object,
        [inputNames.TITLE]: PropTypes.string,
    }),
    post: PropTypes.shape({
        body: PropTypes.object,
        id: PropTypes.string,
        title: PropTypes.string,
    }),
    onCancel: PropTypes.func,
    onChange: PropTypes.func,
    onSubmit: PropTypes.func,
}

export default hoistNonReactStatics(React.memo(PostForm), PostForm)
