import * as React from 'react';
import classNames from 'classnames/bind';

import { Editor } from 'react-draft-wysiwyg';
import { EditorState, convertToRaw, ContentState, Modifier } from 'draft-js';

import FormElement from 'components/structure/FormElement';
import FieldWrapper from 'components/structure/FieldWrapper';

import draftToHtml from 'draftjs-to-html';
import htmlToDraft from 'html-to-draftjs';
import styleIdentifiers from './wysiwyg.scss';

/* eslint import/no-unresolved : "off" */

import '!style-loader!css-loader!react-draft-wysiwyg/dist/react-draft-wysiwyg.css';

const styles = classNames.bind(styleIdentifiers);

export type WysiwygProps = FormElementProps &
  FieldWrapperProps &
  FormItemLabelProps & { name: string; placeholder?: string };

interface WysiwygState {
  editorState?: any;
  code: boolean;
}

class CustomOption extends React.Component {
  addCustomOption: Function = (): void => {
    const { editorState, onChange, custom } = this.props;
    const contentState = Modifier.replaceText(
      editorState.getCurrentContent(),
      editorState.getSelection(),
      custom,
      editorState.getCurrentInlineStyle(),
    );
    onChange(EditorState.push(editorState, contentState, 'insert-characters'));
  };

  render() {
    const { text } = this.props;
    return <div onClick={this.addCustomOption}>{text}</div>;
  }
}

export default class Wysiwyg extends React.Component<WysiwygProps, WysiwygState> {
  constructor(props: WysiwygProps) {
    super(props);
    this.state = {
      code: false,
    };
  }

  componentDidMount() {
    this.handleProps();
  }

  componentDidUpdate(prevProps: WysiwygProps) {
    const { input } = this.props;
    if ((!prevProps.input || !prevProps.input.value) && input && input.value) {
      this.handleProps();
    }
  }

  onEditorStateChange = (editorState: any) => {
    const { input } = this.props;
    const rawContentState = convertToRaw(editorState.getCurrentContent());
    const markup = draftToHtml(
      rawContentState,
      // hashtagConfig,
      // directional,
      // customEntityTransform,
    );

    // item.value = markup;
    this.setState({
      editorState,
    });

    if (input) input.onChange(markup);
  };

  handleProps = () => {
    const { input } = this.props;

    const html = (input && input.value) || '';
    const contentBlock = htmlToDraft(html);
    if (contentBlock) {
      const contentState = ContentState.createFromBlockArray(contentBlock.contentBlocks);
      const editorState = EditorState.createWithContent(contentState);
      this.setState({
        editorState,
      });
    }
  };

  switchType = () => {
    const { code } = this.state;
    if (code) {
      this.handleProps();
    }

    this.setState({ code: !code });
  };

  renderCustomOptions = () => {
    const { customOptions } = this.props;
    const options = [];
    if (customOptions && customOptions.length !== 0) {
      for (let index = 0; index < customOptions.length; index++) {
        const element = customOptions[index];
        options.push(<CustomOption text={element.label} custom={element.insert} />);
      }
    }
    return options;
  };

  // <CustomOption text="download" custom="<DownloadFile />" />

  render() {
    const { editorState, code } = this.state;
    const { className, valueClassName, input, disabled, name, effect, placeholder } = this.props;
    if (!editorState) return false;
    return (
      <FormElement {...this.props} className={styles('Wysiwyg', className)}>
        <FieldWrapper
          {...this.props}
          valueClassName={styles('editor-wrapper', code && 'code-wrapper', valueClassName)}
        >
          <div className={styles('switch', code && 'code')}>
            <div className={styles('text')} onClick={this.switchType}>
              {!code ? 'Switch to code' : 'Go back to editor'}
            </div>
          </div>
          {!code ? (
            <Editor
              editorState={editorState}
              // toolbarClassName="toolbarClassName"
              // wrapperClassName="wrapperClassName"
              editorClassName={styles('editor')}
              onEditorStateChange={this.onEditorStateChange}
              toolbarCustomButtons={this.renderCustomOptions()}
              toolbar={{
                options: [
                  'inline',
                  'blockType',
                  'fontSize',
                  // 'fontFamily',
                  'list',
                  'textAlign',
                  'colorPicker',
                  'link',
                  'embedded',
                  'image',
                  'remove',
                  'history',
                ],
              }}
            />
          ) : (
            <textarea
              disabled={disabled}
              name={name}
              rows={15}
              placeholder={(!effect && placeholder) || ''}
              {...input}
            />
          )}
        </FieldWrapper>
      </FormElement>
    );
  }
}
