import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Editor, EditorState, RichUtils } from 'draft-js';
import ToggleButton from '@material-ui/lab/ToggleButton';
import ToggleButtonGroup from '@material-ui/lab/ToggleButtonGroup';
import BoldIcon from '@material-ui/icons/FormatBold';
import ItalicIcon from '@material-ui/icons/FormatItalic';
import { withStyles } from '@material-ui/core/styles';
import { stateToHTML } from 'draft-js-export-html';
import { stateFromHTML } from 'draft-js-import-html';

/** */
class TextEditor extends Component {
  /** */
  constructor(props) {
    super(props);
    this.state = {
      editorState: EditorState.createWithContent(stateFromHTML(props.annoHtml)),
    };
    this.onChange = this.onChange.bind(this);
    this.handleKeyCommand = this.handleKeyCommand.bind(this);
    this.handleFormating = this.handleFormating.bind(this);
    this.handleFocus = this.handleFocus.bind(this);
    this.editorRef = React.createRef();
  }

  /**
   * This is a kinda silly hack (but apparently recommended approach) to
   * making sure the whole visible editor area is clickable, not just the first line.
   */
  handleFocus() {
    if (this.editorRef.current) this.editorRef.current.focus();
  }

  /** */
  handleFormating(e, newFormat) {
    const { editorState } = this.state;
    this.onChange(RichUtils.toggleInlineStyle(editorState, newFormat));
  }

  /** */
  handleKeyCommand(command, editorState) {
    const newState = RichUtils.handleKeyCommand(editorState, command);
    if (newState) {
      this.onChange(newState);
      return 'handled';
    }
    return 'not-handled';
  }

  /** */
  onChange(editorState) {
    const { updateAnnotationBody } = this.props;
    this.setState({ editorState });
    if (updateAnnotationBody) {
      const options = {
        inlineStyles: {
          BOLD: { element: 'b' },
          ITALIC: { element: 'i' },
        },
      };
      updateAnnotationBody(stateToHTML(editorState.getCurrentContent(), options).toString());
    }
  }

  /** */
  render() {
    const { classes } = this.props;
    const { editorState } = this.state;
    const currentStyle = editorState.getCurrentInlineStyle();

    return (
      <div>
        <ToggleButtonGroup
          size="small"
          value={currentStyle.toArray()}
        >
          <ToggleButton
            onClick={this.handleFormating}
            value="BOLD"
          >
            <BoldIcon />
          </ToggleButton>
          <ToggleButton
            onClick={this.handleFormating}
            value="ITALIC"
          >
            <ItalicIcon />
          </ToggleButton>
        </ToggleButtonGroup>

        <div className={classes.editorRoot} onClick={this.handleFocus}>
          <Editor
            editorState={editorState}
            handleKeyCommand={this.handleKeyCommand}
            onChange={this.onChange}
            ref={this.editorRef}
          />
        </div>
      </div>
    );
  }
}

/** */
const styles = (theme) => ({
  editorRoot: {
    borderColor: theme.palette.type === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)',
    borderRadius: theme.shape.borderRadius,
    borderStyle: 'solid',
    borderWidth: 1,
    fontFamily: theme.typography.fontFamily,
    marginBottom: theme.spacing(1),
    marginTop: theme.spacing(1),
    minHeight: theme.typography.fontSize * 6,
    padding: theme.spacing(1),
  },
});

TextEditor.propTypes = {
  annoHtml: PropTypes.string,
  classes: PropTypes.shape({
    editorRoot: PropTypes.string,
  }).isRequired,
  updateAnnotationBody: PropTypes.func,
};

TextEditor.defaultProps = {
  annoHtml: '',
  updateAnnotationBody: () => {},
};

export default withStyles(styles)(TextEditor);