/*
 * @Description: quill 编辑器
 * @Author: tangjiang
 * @Github:
 * @Date: 2019-12-18 08:49:30
 * @LastEditors  : tangjiang
 * @LastEditTime : 2020-02-05 11:23:03
 */
import './index.scss';
import 'quill/dist/quill.core.css'; // 核心样式
import 'quill/dist/quill.snow.css'; // 有工具栏
import 'quill/dist/quill.bubble.css'; // 无工具栏
import 'katex/dist/katex.min.css'; // katex 表达式样式
import './font.css'
import React, { useState, useRef, useEffect } from 'react';
import Quill from 'quill';
import katex from 'katex';
import deepEqual from './deepEqual.js'
import { fetchUploadImage } from '../../services/ojService.js';
import { getImageUrl } from 'educoder'
import ImageBlot from './ImageBlot';
import FillBlot from './FillBlot';
var Size = Quill.import('attributors/style/size');
// const Color = Quill.import('attributes/style/color');
Size.whitelist = ['14px', '16px', '18px', '20px', false];
var fonts = ['Microsoft-YaHei','SimSun', 'SimHei','KaiTi','FangSong'];
var Font = Quill.import('formats/font');
Font.whitelist = fonts; //将字体加入到白名单
window.Quill = Quill;
window.katex = katex;
Quill.register(ImageBlot);
Quill.register(Size);
Quill.register(Font, true);
// Quill.register({'modules/toolbar': Toolbar});
Quill.register({
  'formats/fill': FillBlot
});
// Quill.register(Color);


function QuillForEditor ({
  placeholder,
  readOnly,
  autoFocus = false,
  options,
  value,
  imgAttrs = {}, // 指定图片的宽高
  style = {},
  wrapStyle = {},
  showUploadImage,
  onContentChange,
  addFill, // 点击填空成功的回调
  deleteFill // 删除填空，返回删除的下标
  // getQuillContent
}) {
  // toolbar 默认值
  const defaultConfig = [
    'bold', 'italic', 'underline',
    {size: ['14px', '16px', '18px', '20px']},
    {align: []}, {list: 'ordered'}, {list: 'bullet'}, // 列表
    {script: 'sub'}, {script: 'super'},
    { 'color': [] }, { 'background': [] },
		{ 'font': []},
    {header: [1,2,3,4,5,false]},
    'blockquote', 'code-block',
    'link', 'image', 'video',
    'formula',
    'clean'
  ];

  const editorRef = useRef(null);
  // quill 实例
  const [quill, setQuill] = useState(null);
  const [selection, setSelection] = useState(null);
  const [fillCount, setFillCount] = useState(0);
  const [quillCtx, setQuillCtx] = useState({});

  // 文本内容变化时
  const handleOnChange = content => {
    // getQuillContent && getQuillContent(quill);
    onContentChange && onContentChange(content, quill);
  };

  const renderOptions = options || defaultConfig;

  const bindings = {
    tab: {
      key: 9,
      handler: function () {
        console.log('调用了tab=====>>>>');
      }
    },
    backspace: {
      key: 'Backspace',
      /**
       * @param {*} range
       *  { index, // 删除元素的位置
       *    length // 删除元素的个数, 当删除一个时， length=0， 其它等于删除的元素的个数
       *  }
       * @param {*} context 上下文
       */
      handler: function (range, context) {
        /**
         * index: 删除元素的位置
         * length: 删除元素的个数
         */
        const {index, length} = range;
        const _start = length === 0 ? index - 1 : index;
        const _length = length || 1;
        let delCtx = this.quill.getText(_start, _length); // 删除的元素
        // aa
        const reg = /▁/g;
        const delArrs = delCtx.match(reg);
        if (delArrs) {
          const r = window.confirm('确定要删除吗?');
          if (r) {
            let leaveCtx; // 获取删除元素之前的内容
            if (length === 0) {
              leaveCtx = this.quill.getText(0, index - 1);
            } else {
              leaveCtx = this.quill.getText(0, index);
            }
            const leaveArrs = leaveCtx.match(reg);
            const leaveLen = (leaveArrs || []).length;
            let delIndexs = [];
            // 获取删除元素的下标
            delArrs.forEach((item, i) => {
              leaveLen === 0 ? delIndexs.push(i) : delIndexs.push(leaveLen + i);
            });
            deleteFill && deleteFill(delIndexs); // 调用删除回调, 返回删除的元素下标[]
            return true
          } else {
            return false;
          }
        }
        return true;
      }
    }
  };
  // quill 配置信息
  const quillOption = {
    modules: {
      toolbar: renderOptions,
      keyboard: {
        bindings: bindings
      }
      // toolbar: {
      //   container: renderOptions
      // }
    },
    readOnly,
    placeholder,
    theme: readOnly ? 'bubble' : 'snow',
  };


  useEffect(() => {

    const quillNode = document.createElement('div');
    editorRef.current.appendChild(quillNode);
    const _quill = new Quill(editorRef.current, quillOption);

    setQuill(_quill);
    // 处理图片上传功能
    _quill.getModule('toolbar').addHandler('image', (e) => {
      const input = document.createElement('input');
      input.setAttribute('type', 'file');
      input.setAttribute('accept', 'image/*');
      input.click();

      input.onchange = async (e) => {
        const file = input.files[0]; // 获取文件信息
        const formData = new FormData();
        formData.append('file', file);

        const range = _quill.getSelection(true);
        let fileUrl = ''; // 保存上传成功后图片的url
        // 上传文件
        const result = await fetchUploadImage(formData);
        // 获取上传图片的url
        if (result.data && result.data.id) {
          fileUrl = getImageUrl(`api/attachments/${result.data.id}`);
        }
        // 根据id获取文件路径
        const { width, height } = imgAttrs;
        // console.log('上传图片的url:', fileUrl);
        if (fileUrl) {
          _quill.insertEmbed(range.index, 'image', {
            url: fileUrl,
            alt: '图片信息',
            onClick: showUploadImage,
            width,
            height
          });
        }
      }
    });
    // 处理填空
    _quill.getModule('toolbar').addHandler('fill', (e) => {
      // alert(1111);
      setFillCount(fillCount + 1);
      const range = _quill.getSelection(true);
      _quill.insertText(range.index, '▁');
      addFill && addFill(); // 调用添加回调
    });
  }, []);

  // 设置值
  useEffect(() => {
    if (!quill) return

    const previous = quill.getContents()

    if (value && value.hasOwnProperty('ops')) {
      // console.log(value.ops);
      const ops = value.ops || [];
      ops.forEach((item, i) => {
        if (item.insert['image']) {
          item.insert['image'] = Object.assign({}, item.insert['image'], {style: { cursor: 'pointer' }, onclick: (url) => showUploadImage(url)});
        }
      });
    }

    const current = value
    if (!deepEqual(previous, current)) {
      setSelection(quill.getSelection())
      if (typeof value === 'string' && value) {
      	// debugger
        quill.clipboard.dangerouslyPasteHTML(value, 'api');
        if (autoFocus) {
          quill.focus();
        } else {
          quill.blur();
        }
      } else {
        quill.setContents(value)
        if (autoFocus) quill.focus();
      }
    }
  }, [quill, value, setQuill, autoFocus]);

  // 清除选择区域
  useEffect(() => {
    if (quill && selection) {
      quill.setSelection(selection)
      setSelection(null)
    }
  }, [quill, selection, setSelection]);

  // 设置placeholder值
  useEffect(() => {
    if (!quill || !quill.root) return;
    quill.root.dataset.placeholder = placeholder;
  }, [quill, placeholder]);

  // 处理内容变化
  useEffect(() => {
    if (!quill) return;
    if (typeof handleOnChange !== 'function') return;
    let handler;
    quill.on(
      'text-change',
      (handler = (delta, oldDelta, source) => {
        const _ctx = quill.getContents();
        setQuillCtx(_ctx);
        handleOnChange(quill.getContents()); // getContents: 检索编辑器内容
      })
    );
    return () => {
      quill.off('text-change', handler);
    }
  }, [quill, handleOnChange]);

  // 返回结果
  return (
      <div className='quill_editor_for_react_area' style={wrapStyle}>
        <div ref={editorRef} style={style}></div>
      </div>
  );
}

export default QuillForEditor;
