import React, { useState } from "react";
import classnames from "classnames";
import BraftEditor, { ControlType, EditorState } from "braft-editor";
import styles from "./index.less";
import "braft-editor/dist/index.css";

// 引入表情包扩展模块样式文件
import "braft-extensions/dist/emoticon.css";
// 引入表情包扩展模块和默认表情包列表
import Emoticon, { defaultEmoticons } from "braft-extensions/dist/emoticon";
import MaxLength from "braft-extensions/dist/max-length";

const lengthOptions = {
  defaultValue: 100 // 指定默认限制数，如不指定则为Infinity(无限)
  // includeEditors: ['editor-id-1'], // 指定该模块对哪些BraftEditor生效，不传此属性则对所有BraftEditor有效
  // excludeEditors: ['editor-id-2'],  // 指定该模块对哪些BraftEditor无效
};
BraftEditor.use(MaxLength(lengthOptions));

// 转换默认表情包列表，让webpack可以正确加载到默认表情包中的图片，请确保已对png格式的文件配置了loader
// 如果你使用的webpack版本不支持动态require，或者使用的其他打包工具，请勿使用此写法
const emoticons = defaultEmoticons.map((item: string) =>
  require(`braft-extensions/dist/assets/${item}`)
);

// 也可以使用自己的表情包资源，不受打包工具限制
// const emoticons = ['http://path/to/emoticon-1.png', 'http://path/to/emoticon-2.png', 'http://path/to/emoticon-3.png', 'http://path/to/emoticon-4.png', ...]

const emotionOptions = {
  // includeEditors: ['editor-id-1'], // 指定该模块对哪些BraftEditor生效，不传此属性则对所有BraftEditor有效
  // excludeEditors: ['editor-id-2'],  // 指定该模块对哪些BraftEditor无效
  emoticons: emoticons, // 指定可用表情图片列表，默认为空
  closeOnBlur: true, // 指定是否在点击表情选择器之外的地方时关闭表情选择器，默认false
  closeOnSelect: false // 指定是否在选择表情后关闭表情选择器，默认false
};

BraftEditor.use(Emoticon(emotionOptions));

export interface BaseEditorProps {
  value: EditorState;
  onChange: (editorState: EditorState) => void;
  contentStyle?: React.CSSProperties;
  controls?: ControlType[];
  FloatControls?: any;
  
  blockRenderMap?: any;
  blockRendererFn?: any;
  draftProps?: any;
  placeholder?: string;
  converts?: any;
}

export const BarftEditorPage = ({
  value,
  onChange,
  controls,
  contentStyle = {},
  FloatControls,
  draftProps,
  placeholder,
  blockRenderMap,
  blockRendererFn,
  converts,
}: BaseEditorProps) => {
  const optionsControls = controls
    ? controls
    : [
        "bold",
        "italic",
        "underline",
        "separator",
        "link",
        "emoji",
        "separator",
        "media"
      ];
  const options: any = {
    controls: optionsControls,
    showControlsBar:
      optionsControls && optionsControls.length > 0 && !FloatControls,
    showFloatControls: FloatControls
  };

  const [focusState, setFocusState] = useState(false);

  return (
    <div className={styles.baseWrapper}>
      <BraftEditor
        value={value}
        onChange={onChange}
        controls={options.controls}
        controlBarClassName={classnames(styles.controlBar, {
          [styles.focus]: focusState
        })}
        controlBarStyle={options.showControlsBar ? {} : { display: "none" }}
        contentClassName={classnames(styles.editorContent, {
          [styles.focus]: focusState,
          [styles.hasFloatControls]: options.showFloatControls
        })}
        contentStyle={contentStyle}
        onFocus={() => setFocusState(true)}
        onBlur={() => setFocusState(false)}
        hooks={{
          "toggle-link": ({ href, target }) => {
            href = href.indexOf("http") === 0 ? href : `http://${href}`;
            return { href, target };
          }
        }}
        {...{
          blockRenderMap,
          blockRendererFn,
          converts,
          placeholder,
          draftProps,
        }}
      />
      {options.showFloatControls ? (
        <div className={classnames(styles.floatControls)}>
          {
            <FloatControls
              editorState={value}
              setEditorState={onChange}
            />
          }
        </div>
      ) : null}
    </div>
  );
};

export default BarftEditorPage;
