<template>
    <div>
        <!-- 图片上传组件辅助-->
        <el-upload
                class="avatar-uploader"
                action="notnull"
                :http-request="uploadFileFun"
                name="img"
                :headers="header"
                :show-file-list="false"
                :on-success="uploadSuccess"
                :on-error="uploadError"
                :before-upload="beforeUpload"
                v-show="false">
            <el-button class="stBtnUpload" size="small" type="primary">点击上传</el-button>
        </el-upload>
        <el-button   style="display: none" @click="richtext()" size="small" type="primary">返回</el-button>
        <quill-editor
                class="editor"
                v-model="content"
                :ref="quillEditorRef"
                :options="editorOption"
                @blur="onEditorBlur($event)" @focus="onEditorFocus($event)"
                @change="onEditorChange($event)">
        </quill-editor>
    </div>
</template>
<script>
    let cusSpecial = ['α', 'β', 'γ'];
    // 工具栏配置
    const toolbarOptions = [
        ['bold', 'italic', 'underline', 'strike'], // 加粗 斜体 下划线 删除线
        ['blockquote', 'code-block', 'formula'], // 引用  代码块
        [{ header: 1 }, { header: 2 }], // 1、2 级标题
        [{ list: 'ordered' }, { list: 'bullet' }], // 有序、无序列表
        [{ script: 'sub' }, { script: 'super' }], // 上标/下标
        [{ indent: '-1' }, { indent: '+1' }], // 缩进
        // [{'direction': 'rtl'}],                         // 文本方向
        [{ size: ['small', false, 'large', 'huge'] }], // 字体大小
        [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题
        [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
        [{ font: [] }], // 字体种类
        [{ align: [] }], // 对齐方式
        ['clean'], // 清除文本格式
        ['link', 'image', 'video'], // 链接、图片、视频
        cusSpecial, // 特殊符号
    ];

    import { quillEditor } from 'vue-quill-editor';
    import * as Quill      from 'quill';
    import * as Delta      from 'quill-delta';
    import ImageResize     from 'quill-image-resize-module';
    import StImage         from './QuillEditorStBlockEmbed';

    Quill.register('modules/imageResize', ImageResize);
    Quill.register('formats/stImage', StImage);

    import 'quill/dist/quill.core.css';
    import 'quill/dist/quill.snow.css';
    import 'quill/dist/quill.bubble.css';

    import { getUploadImg }    from '@/api/AlCloud';
    import { getUploadConfig } from '@/api/base64';
    import axios               from 'axios';
    import store               from '@/store';

    export default {
        props:      {
            /*编辑器的内容*/
            value:          {
                type: String,
            },
            flg:            {
                type: String,
            },
            quillEditorRef: {
                type: String,
            },
            /*图片大小*/
            maxSize:        {
                type:    Number,
                default: 4000, //kb
            },
        },
        components: {
            quillEditor,
        },
        data() {
            return {
                curLength:       0,
                uploadfileParam: {},
                content:         this.value,
                quillUpdateImg:  false, // 根据图片上传状态来确定是否显示loading动画，刚开始是false,不显示
                editorOption:    {
                    theme:       'snow', // or 'bubble'
                    placeholder: '请输入内容...',
                    modules:     {
                        toolbar:     {
                            container: toolbarOptions,
                            handlers:  {
                                image:     function (value) {
                                    if (value) {
                                        // 触发input框选择图片文件
                                        // this.$refs[this.btnRef].click();
                                        this.container.parentElement.parentElement.children[0].children[0].children[0].click();
                                        this.container.parentElement.parentElement.children[1].click();
                                    } else {
                                        this.quill.format('image', false);
                                    }
                                },
                                'formula': (value) => {
                                    let quill = this.$refs[this.quillEditorRef].quill;
                                    this.curLength = quill.getSelection() ? quill.getSelection().index : 0;
                                    let chuck = this.getSelectionLatex();
                                    if (chuck) {
                                        this.formula.latex = chuck.latex;
                                        this.formula.type = chuck.type;
                                    } else {
                                        this.formula.latex = '';
                                        this.formula.type = '';
                                    }

                                    this.formula.dialogVisible = true;
                                    this.formula.quillEditorRef = this.quillEditorRef;

                                    store.commit({
                                                     type:      'setFormula'
                                                     , formula: this.formula,
                                                 });
                                },
                                'α':       (value) => {
                                    let quill = this.$refs[this.quillEditorRef].quill;
                                    // 获取光标所在位置
                                    let length = quill.getSelection().index;
                                    // 插入图片  res.url为服务器返回的图片地址
                                    /*quill.insertEmbed(length, 'image', `${multipartParams.url}/${multipartParams.key}`);
                                    // 调整光标到最后
                                    quill.setSelection(length + 1);*/
                                    quill.insertText(length, 'α');
                                    quill.setSelection(length + 1);
                                },
                                'β':       (value) => {
                                    let quill = this.$refs[this.quillEditorRef].quill;
                                    // 获取光标所在位置
                                    let length = quill.getSelection().index;
                                    // 插入图片  res.url为服务器返回的图片地址
                                    /*quill.insertEmbed(length, 'image', `${multipartParams.url}/${multipartParams.key}`);
                                    // 调整光标到最后
                                    quill.setSelection(length + 1);*/
                                    quill.insertText(length, 'β');
                                    quill.setSelection(length + 1);
                                },
                                'γ':       (value) => {
                                    let quill = this.$refs[this.quillEditorRef].quill;
                                    // 获取光标所在位置
                                    let length = quill.getSelection().index;
                                    // 插入图片  res.url为服务器返回的图片地址
                                    /*quill.insertEmbed(length, 'image', `${multipartParams.url}/${multipartParams.key}`);
                                    // 调整光标到最后
                                    quill.setSelection(length + 1);*/
                                    quill.insertText(length, 'γ');
                                    quill.setSelection(length + 1);
                                },
                            },
                        },
                        imageResize: {},
                    },
                },
                // serverUrl: "/v1/blog/imgUpload", // 这里写你要上传的图片服务器地址
                header:          {
                    // token: sessionStorage.token
                }, // 有的图片服务器要求请求头需要有token
                currentImgSrc:   '',
                sttipinputw:     0,
                sttipinputh:     0,
                formula:         {
                    dialogVisible:  false,
                    imgsrc:         '',
                    latex:          '',
                    type:           '',
                    quillEditorRef: '',
                },
            };
        },

        methods: {

            //  describe: 此功能用户放切屏点击图片失去焦点 author: Wgy date:2020-07-07
            richtext(){
                window.onblur = null;
                this.$emit('richText','richtext');
            },
            onEditorBlur() {
                //失去焦点事件
            },
            onEditorFocus() {
                //获得焦点事件
            },
            onEditorChange() {
                //内容改变事件
                this.$emit('syncValue', this.flg, this.content);
            },

            // 富文本图片上传前
            beforeUpload() {
                // 显示loading动画
                this.quillUpdateImg = true;
            },

            uploadSuccess(res, file) {
            },
            // 富文本图片上传失败
            uploadError() {
                // loading动画消失
                this.quillUpdateImg = false;
            },
            uploadFileFun(truck) {
                var file = truck.file;
                const suffix = file.name.split('.').pop();
                var dd = new Date();
                var y = dd.getFullYear();
                var m = dd.getMonth() + 1;//获取当前月份的日期
                const options = {
                    prefix: 'resource/QuillEditor/' + y + m + '/',
                    suffix: suffix,
                };

                getUploadImg(options).then((res) => {
                    if (res.code === 0) {
                        // 二进制文件通过forData对象进行传递
                        const FormDataForAl = new FormData();
                        const multipartParams = Object.assign({}, res.data, {
                            Filename:              `images/${file.name}`,
                            success_action_status: '200',
                        });
                        // 参数数据
                        FormDataForAl.append('key', multipartParams.key);
                        FormDataForAl.append('policy', multipartParams.policy);
                        FormDataForAl.append('signature', multipartParams.signature);
                        FormDataForAl.append('OSSAccessKeyId', multipartParams.accessid);
                        FormDataForAl.append('success_action_status', multipartParams.success_action_status);
                        // OSS要求, file放到最后
                        FormDataForAl.append('file', file);

                        axios.post(multipartParams.uploadUrl, FormDataForAl).then(alRes => {
                            if (alRes.status === 200) {
                                let quill = this.$refs[this.quillEditorRef].quill;
                                // 获取光标所在位置
                                let length = quill.getSelection().index;
                                // 插入图片  res.url为服务器返回的图片地址
                                quill.insertEmbed(length, 'image', `${multipartParams.downloadUrl}/${multipartParams.key}`);


                                // 调整光标到最后
                                quill.setSelection(length + 1);
                            }
                        }).catch(alerr => {
                            this.$message.error('图片插入失败');
                            console.error('阿里云错误', alerr);
                        });
                    }
                });


            },
            clearContent() {
                this.content = '';
            },
            setContent(val) {
                this.content = val;
            },
            quillEditorAddEventListener() {
                let dom = this.$refs[this.quillEditorRef].$el.children[1].children[0];
                let quill = this.$refs[this.quillEditorRef].quill;
                let that = this;
                var pasteFun = function (e) {
                    var clipboardData = e.clipboardData;
                    if (!(clipboardData && clipboardData.items)) {//是否有粘贴内容
                        return;
                    }
                    for (var i = 0; i < clipboardData.items.length; i++) {
                        var item = clipboardData.items[i];
                        if (item.kind === 'string' && item.type === 'text/plain') {
                            item.getAsString((str) => {
                                // str 是获取到的字符串,创建文本框
                                //处理粘贴的文字内容
                                setTimeout(() => {
                                    let length = quill.getSelection().index;
                                    // 插入
                                    quill.insertText(length, str);
                                    // 调整光标到最后
                                    quill.setSelection(length + str.length);
                                }, 50);
                            });
                        } else if (item.kind === 'file') {//file 一般是各种截图base64数据
                            var pasteFile = item.getAsFile();
                            // pasteFile就是获取到的文件
                            var reader = new FileReader();
                            reader.onload = function (event) {
                                var base64Img = event.target.result;
                                // image/png;base64,
                                let base64ImgPrefix = base64Img.substring(0, base64Img.indexOf(',') + 1);
                                let base64ImgData = base64Img.substring(base64Img.indexOf(',') + 1);
                                let opt = {
                                    'data':   base64ImgData,
                                    'prefix': 'resource/',
                                    'suffix': base64ImgPrefix.substring(base64ImgPrefix.indexOf('/') + 1, base64ImgPrefix.indexOf(';')),
                                };
                                getUploadConfig(opt).then(res => {
                                    if (res.code === 0) {
                                        let uri = res.data;

                                        // 获取光标所在位置
                                        let length = quill.getSelection().index;
                                        // 插入图片  res.url为服务器返回的图片地址
                                        quill.insertEmbed(length, 'image', uri);
                                        // 调整光标到最后
                                        quill.setSelection(length + 1);
                                    } else {
                                        that.$message.error('图片插入失败');
                                    }

                                });
                            }; // data url
                            reader.readAsDataURL(pasteFile);
                        }
                    }
                };
                dom.removeEventListener('paste', pasteFun);
                dom.addEventListener('paste', pasteFun);
            },

            getSelectionLatex() {
                let type = '';
                let leaf = null;
                // 如果光标前一个是公式 取得公式的latex
                let quill = this.$refs[this.quillEditorRef].quill;
                let selection = quill.getSelection();
                if (!selection) {
                    return null;
                }

                if (selection.length === 0) {
                    type = 'rightSingle';
                    leaf = quill.getLeaf(selection.index);
                } else {
                    type = 'selected';
                    leaf = quill.getLeaf(selection.index + 1);
                }
                // let contents = quill.getContents();

                // let line = quill.getLine(selection.index);
                // let bounds = quill.getBounds(selection.index);
                // console.log(selection, leaf);

                if (leaf[0] instanceof StImage) {
                    // console.log(leaf[0].domNode.dataset.latex);
                    return {
                        type:  type,
                        latex: leaf[0].domNode.dataset.latex,
                    };
                }
                return null;
            },
            // Delta operation
            delQuillContent(index) {
                let quill = this.$refs[this.quillEditorRef].quill;
                /*console.dir(quill);
                console.dir(quill.getSelection());
                console.dir(quill.getContents());*/

                //  .insert('White', { color: '#fff' })
                var stDelta = new Delta().retain(index).delete(1);
                let quillContents = quill.getContents().compose(stDelta);
                quill.setContents(quillContents);
            },
            passValue() {
                // console.log('do passValue!!');
                let latex = this.formula.latex;
                if (latex.indexOf('placeholder') > -1) {
                    this.formula.dialogVisible = false;
                    let quill = this.$refs[this.quillEditorRef].quill;
                    quill.setSelection(this.curLength);
                    return;
                }

                if (latex && latex !== '') {

                    if (this.formula.type === 'rightSingle') {
                        // del formula
                        this.delQuillContent(this.curLength - 1);

                        let quill = this.$refs[this.quillEditorRef].quill;
                        // 获取光标所在位置
                        // let length = quill.getSelection() ? quill.getSelection().index : 0;
                        // 插入图片  res.url为服务器返回的图片地址
                        quill.insertEmbed(this.curLength - 1, 'stimage', {
                            src:          this.formula.imgsrc,
                            'data-latex': latex,
                        });
                        // quill.formatText(length, 1, { 'data-latex': latex });
                        /*var delta = quill.getContents();
                        console.log(delta);*/
                        // 调整光标到最后
                        // quill.insertText(length, img);
                        quill.setSelection(this.curLength);
                    } else if (this.formula.type === 'selected') {
                        // del formula
                        this.delQuillContent(this.curLength);
                        let quill = this.$refs[this.quillEditorRef].quill;
                        // 获取光标所在位置
                        // let length = quill.getSelection() ? quill.getSelection().index : 0;
                        // 插入图片  res.url为服务器返回的图片地址
                        quill.insertEmbed(this.curLength, 'stimage', {
                            src:          this.formula.imgsrc,
                            'data-latex': latex,
                        });
                        // quill.formatText(length, 1, { 'data-latex': latex });
                        /*var delta = quill.getContents();
                        console.log(delta);*/
                        // 调整光标到最后
                        // quill.insertText(length, img);
                        quill.setSelection(this.curLength + 1);
                    } else {
                        let quill = this.$refs[this.quillEditorRef].quill;
                        // 获取光标所在位置
                        // let length = quill.getSelection() ? quill.getSelection().index : 0;
                        // 插入图片  res.url为服务器返回的图片地址
                        quill.insertEmbed(this.curLength, 'stimage', {
                            src:          this.formula.imgsrc,
                            'data-latex': latex,
                        });
                        // quill.formatText(length, 1, { 'data-latex': latex });
                        /*var delta = quill.getContents();
                        console.log(delta);*/
                        // 调整光标到最后
                        // quill.insertText(length, img);
                        quill.setSelection(this.curLength + 1);
                        this.formula.dialogVisible = false;
                    }

                    this.formula.dialogVisible = false;
                }
            },
        },
        mounted() {

            let checkCount = 0;
            let checkCountMax = 100;
            let stInterval = setInterval(() => {
                if (this.quillEditorRef) {
                    clearInterval(stInterval);
                    this.$nextTick(function () {
                        this.quillEditorAddEventListener();
                    });
                    /*let dom = this.$refs[this.quillEditorRef].$el.children[1].children[0];
                    const specialSignals = document.querySelectorAll('.ql-special-signal');
                    for (const specialSignal of specialSignals) {
                        // specialSignal.style.cssText = "width:80px; border:1px solid #ccc; border-radius:5px;";
                        // specialSignal.style.cssText = "width:50px;";
                        // specialSignal.innerText="特殊符号";

                        specialSignal.classList.add('el-icon-edit-outline');
                        specialSignal.title = "特殊符号";
                    }*/

                    for (const special of cusSpecial) {
                        const specialSignals = document.querySelectorAll('.ql-' + special);
                        for (const specialSignal of specialSignals) {
                            // specialSignal.style.cssText = "width:80px; border:1px solid #ccc; border-radius:5px;";
                            // specialSignal.style.cssText = "width:50px;";
                            specialSignal.innerText = special;

                            // specialSignal.classList.add('el-icon-edit-outline');
                            specialSignal.title = special;
                        }
                    }


                } else {
                    if (checkCount > checkCountMax) {
                        clearInterval(stInterval);
                    }
                }
                checkCount++;
            }, 100);
            /*监听富文本复制粘贴*/
            document.onpaste = function (e) {
                let arrPath = e.path;
                let has = false;
                if (arrPath) {
                    for (const path of arrPath) {
                        if (path.className && path.className.indexOf('ql-editor') > -1) {
                            has = true;
                            break;
                        }
                    }
                }
                if (has) {
                    e.preventDefault();
                }
            };
        },
        watch:   {
            '$store.state.formula': {
                handler(newVal, oldVal) {
                    // console.log('in store.state.formula');
                    // console.log(newVal);
                    this.formula = newVal;
                    /*console.dir('======start=======');
                    console.dir(this.formula.quillEditorRef);
                    console.dir(this.quillEditorRef);
                    console.dir('======end=======');*/
                    if (this.formula.dialogVisible === false && this.formula.quillEditorRef === this.quillEditorRef) {
                        this.passValue();
                    }
                },
                deep: true,
            },
        },
    };

</script>
