import React from "react";
import PropTypes from "prop-types";
import { Editor, EditorState, DraftEditorCommand, RichUtils, Modifier, ContentState, convertToRaw, ContentBlock, CompositeDecorator, Entity, SelectionState, AtomicBlockUtils } from "draft-js";
import styles from "./RichTextEditor.less";

interface RichTextEditorProps {}
interface RichTextEditorState {
  editorState: EditorState;
}

// 自定义组件，用于超链接
const Link = (props: any) => {
    // 这里通过contentState来获取entity�，之后通过getData获取entity中包含的数据
    const { url } = props.contentState.getEntity(props.entityKey).getData();
    return (
        <a href={url}>
            {props.children}
        </a>
    )
}
// decorator，用于超链接
const decorator = new CompositeDecorator([
  {
      strategy (contentBlock, callback, contentState) {

          // 这个方法接收2个函数作为参数，如果第一个参数的函数执行时�返回true，就会执行第二个参数函数，同时会�将匹配的�字符的起始位置和结束位置传递给第二个参数。
          contentBlock.findEntityRanges(
              (character) => {
                  const entityKey = character.getEntity();
                  return (
                      entityKey !== null &&
                      contentState.getEntity(entityKey).getType() === 'LINK'
                  );
              }, (...arr) => {
                  callback(...arr)
              }
          );
      },
      component: Link
  },
  {
    strategy (contentBlock, callback, contentState) {
      contentBlock.findEntityRanges(
        (character) => {
          const entityKey = character.getEntity();
          return (
            entityKey !== null &&
            contentState.getEntity(entityKey).getType() === 'EMOJI'
          );
        }, (...arr) => {
          callback(...arr);
        }
      )
    },
    // component: (props: any) => (<span style={{ color: 'red' }}>[Emoji]</span>)
    component: (props: any) => (
      <i style={{
          display:'inline-block',
          height:'18px',
          width:'18px',
          backgroundImage:`url(https://i.pinimg.com/originals/03/7e/79/037e79b2fb52127537be79110891ae3f.png)`,
          backgroundSize:'100% 100%',
          color:'transparent'
  }}>{`e`}</i>)
  }
]);

class RichTextEditor extends React.Component<
  RichTextEditorProps,
  RichTextEditorState
> {
  constructor(props: RichTextEditorProps) {
    super(props);
    this.state = {
      editorState: EditorState.createEmpty(decorator)
    };
    this.onChange = (editorState: EditorState) =>
      this.setState({ editorState });
    this.handleKeyCommand = this.handleKeyCommand.bind(this);
    this.defaultBlockStyleFn = this.defaultBlockStyleFn.bind(this);
  }

  onChange: (editorState: EditorState) => void;
  handleKeyCommand(command: DraftEditorCommand, editorState: EditorState) {
    const newState = RichUtils.handleKeyCommand(editorState, command);
    console.log('command: ', command);
    console.log('newState: ', newState);
    if (newState) {
      this.onChange(newState);
      return "handled";
    }

    switch (command) {
      case 'backspace': 
        const contentState = editorState.getCurrentContent();
        const selectionState = editorState.getSelection();
        const [startOffset, endOffset] = [selectionState.getStartOffset(), selectionState.getEndOffset()];
        if (startOffset === endOffset) {
          // 未选中状态
          console.log(selectionState.getAnchorKey());
        }
        // 选中状态

        break;
      case 'backspace-word': 
      case 'backspace-to-start-of-line':
        break;
    }
    
    return "not-handled";
  }

  _onBoldClick() {
    this.onChange(RichUtils.toggleInlineStyle(this.state.editorState, 'BOLD'));
  }

  _onLinkClick() {
    const { editorState } = this.state;
    const contentState = editorState.getCurrentContent();
    const selectionState = editorState.getSelection();
    const contentStateWithEntity = contentState.createEntity('LINK', 'MUTABLE', {
      url: 'http://www.zombo.com',
    });
    const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
    const contentStateWithLink = Modifier.applyEntity(
      contentStateWithEntity,
      selectionState,
      entityKey,
    );
    const newEditorState = EditorState.push(editorState, contentStateWithLink, 'apply-entity');
    this.onChange(newEditorState);
  }

  _onEmojiClick(e: React.MouseEvent, emojiCode: string) {
    const { editorState } = this.state;
    const contentState = editorState.getCurrentContent();
    const selectionState = editorState.getSelection();
    const EMOJIEntity: ContentState = contentState.createEntity('EMOJI', 'IMMUTABLE', { emojiCode });
    const entityKey = EMOJIEntity.getLastCreatedEntityKey();
    const ncsWithEntity = Modifier.insertText(contentState, selectionState, 'e', undefined, entityKey);
    const newEditorState = EditorState.push(editorState, ncsWithEntity, 'insert-characters');
    // const newEditorState = AtomicBlockUtils.insertAtomicBlock(
    //   editorState,
    //   entityKey,
    //   ' '
    // );
    this.onChange(newEditorState);
  }

  _onCheckRange() {
    console.log(this.state.editorState.getCurrentContent());
    console.log(convertToRaw(this.state.editorState.getCurrentContent()));
  }

  defaultBlockStyleFn(contentBlock: ContentBlock) {
    const type = contentBlock.getType();
    return "";
  }

  defaultBlockRenderFn(contentBlock: ContentBlock) {
    const type = contentBlock.getType();
    return contentBlock;
  }

  render() {
    const { editorState } = this.state;
    return (
      <div className={styles.wrapper}>
        <div className={styles.btnListWrapper}>
          <button onClick={this._onBoldClick.bind(this)}>Bold</button>
          <button onClick={this._onCheckRange.bind(this)}>Check</button>
          <button onClick={this._onLinkClick.bind(this)}>Link</button>
          <button onClick={(e: React.MouseEvent) => this._onEmojiClick(e, '0011')}>Emoji</button>
        </div>
        <div className={styles.editorWrapper}>
          <Editor
            editorState={editorState}
            blockStyleFn={this.defaultBlockStyleFn}
            blockRendererFn={this.defaultBlockRenderFn}
            handleKeyCommand={this.handleKeyCommand}
            onChange={this.onChange}
          />
        </div>
      </div>
    );
  }
}

export default RichTextEditor;
