
import * as _ from 'lodash';
import eventbus from '../../service/eventbus';
// import eventbus from '../../../views/editor/service/eventbus';
import Service from "../../service/tool-service";
import httpLoading from "../../utils/httpLoading";
let common = {
    createNewInstanceKey () {
        return 'gaea_instance_'+Number(Math.random().toString().substr(3,3) + Date.now()).toString(36);
    }
};

const viewport = {
    namespaced: true,
    state: {
        moveInstance: [],//note 存儲要刪除的實例
        localViewportDOM: null,
        localInstanceDoms: new Map(),
        localElement: "",
        localInstances: new Map(),
        viewportDOM: null,
        rootInstanceKey: null,
        instances: new Map(),
        instanceDoms: new Map(),
        currentDragInfo: null,
        currentHoverInstanceKey: null,
        currentEditInstanceKey: null,
        currentFormInstanceKey: null,
        currentInfoCellInstanceKey: null,
        currentBoxInstanceKey: null,
        parentEditInstanceKey: null,
        dragStartDataReady: false,
        isDrag:false,
        pagePriviewData:{},
        /**
         * 跨父級拖动，保存当前的那个对象
         */
        saveDragObj: {},
        /**
         * 鼠标离开视图区域
         */
        mouseLeaveViewport: 'mouseLeaveViewport',



        /**
         * 鼠标离开视图区域
         */
        mouseLeaveComponent: 'mouseLeaveComponent',
        /**
         * 鼠标移动到某个组件上
         */
        mouseHoveringComponent: 'mouseHoveringComponent',
        /**
         * 鼠标移动到面包屑
         */
        mouseHoveringCrumbItem: 'mouseHoveringCrumbItem',
        /**
         * 鼠标移动到面包屑
         */
        mouseLeaveCrumbItem: 'mouseLeaveCrumbItem',
        /**
         * 视图区域发生更新
         */
        viewportUpdated: 'viewportUpdated',
        /**
         * 刷新某个实例
         */
        instanceUpdate: 'instanceUpdate',
        /**
         * 页面冲渲染
         */
        refreshPage: 'refreshPage',
        /**
         * 触发编辑器回调
         */
        emitEditorCallback: 'emitEditorCallback',
        /**
         * 当前点击选组件改变
         */
        currentEditInstanceChange: 'currentEditInstanceChange'
    },
    mutations: {
        startDrag (state, dragInfo) {
            if(dragInfo.info.instanceKey){
                state.currentEditInstanceKey=dragInfo.info.instanceKey;
            }
            state.currentDragInfo = dragInfo;
            console.log("startDrag");
            state.isDrag=true;
        },
        endDrag (state) {
            state.currentDragInfo = null;
            console.log("endDrag");
            state.isDrag=false;
        },
        setViewportDOM (state, viewportDOM) {
            state.viewportDOM = viewportDOM;
        },
        initViewport (state) {
            this.commit('viewport/addInstance', {
                gaeaKey: 'gaea-container',
                parentInstanceKey: null,
                indexPosition: null
            });
            let rootInstance = Array.from(state.instances);
            const rootInstanceKey = rootInstance[0][0];
            this.commit('viewport/setRootInstanceKey', rootInstanceKey);
        },

        //note 当前拖动的实例和目标实例
        dealCurSecontLevel(state,obj){
            //
            let instance = state
                .instances
                .get(obj.currentInstance);
            let parentInstance= state
                .instances
                .get(obj.targetInstance);
            //note 如果已经是根元素, 直接返回空数组,获取父级的level和当前的level

            //note 标示是当前拖动进来的组件   在这里判断当前的是否大于父级的level，如果大于正常，否则删除拖动进来的组件，并提示，不符合规则
            let currLevel=instance.vm.level;
            if(obj.beforeIndex<2||obj.afterIndex<2){

            }
            let data={
                title:"提示",
                content:"拖拽不符合规则"
            }
            state.currentEditInstanceKey=obj.currentInstance;
            //  eventbus.$emit("openModal",data);
            //note 获取存储的实例
            console.log(state.saveDragObj);
            this.commit('viewport/deleteData', state.currentEditInstanceKey);
            state.saveDragObj.indexPosition=obj.beforeIndex;
            setTimeout(()=>{
                instance.key=obj.currentInstance;
                eventbus.$emit("addMoveInstance",state.saveDragObj);
            },800);
            //  }
            return;
        },

        //note 当前拖动的实例和目标实例
        dealCurLevelAndTargetLevel(state,obj){
            //
            debugger;
            let instance = state
                .instances
                .get(obj.currentInstance);
            let parentInstance= state
                .instances
                .get(obj.targetInstance);
            //note 如果已经是根元素, 直接返回空数组,获取父级的level和当前的level
            let parentLevel=parentInstance.vm.level;
            if(!parentLevel){
                return;
            }
            if(instance.gaeaKey=="gaea-cell-table"){
                return;
            }
            //note 标示是当前拖动进来的组件   在这里判断当前的是否大于父级的level，如果大于正常，否则删除拖动进来的组件，并提示，不符合规则
            let currLevel=instance.vm.level;
            /* if(currLevel<=parentLevel){*/
            let data={
                title:"提示",
                content:"拖拽不符合规则"
            }
            state.currentEditInstanceKey=obj.currentInstance;
            //   eventbus.$emit("openModal",data);
            //note 获取存储的实例
            console.log(state.saveDragObj);
            setTimeout(()=>{
                this.commit('viewport/deleteData', state.currentEditInstanceKey);
                instance.key=obj.currentInstance;
                eventbus.$emit("addMoveInstance",state.saveDragObj);
            },800);
            //  }
            return;
        },
        dealLevel(state){
            debugger;
            let instance = state
                .instances
                .get(state.currentEditInstanceKey);
            let parentInstance= state
                .instances
                .get(state.parentEditInstanceKey);
            //note 如果已经是根元素, 直接返回空数组,获取父级的level和当前的level
            if(!instance||instance.parentInstanceKey== "gaea_instance_1"){
                return;
            }
            let parentLevel=parentInstance.vm.level;
            if(!parentLevel){
                return;
            }
            //note 标示是当前拖动进来的组件   在这里判断当前的是否大于父级的level，如果大于正常，否则删除拖动进来的组件，并提示，不符合规则
            let currLevel=instance.vm.level;
            if(instance.gaeaKey=="gaea-cell-table"||parentInstance.gaeaKey=="gaea-info-base"&&instance.gaeaKey=="gaea-cell"){

            }else if(currLevel<=parentLevel){
                let data={
                    title:"提示",
                    content:"拖拽不符合规则"
                }
                eventbus.$emit("openModal",data);
                setTimeout(()=>{
                    this.commit('viewport/deleteData', state.currentEditInstanceKey);
                },800);
            }
            return;
        },
        addInstance (state, params) {
            let newInstanceKey = "";
            if(params.gaeaKey=="gaea-container"){
                newInstanceKey = 'gaea_instance_1';
            }else{
                newInstanceKey = params.newInstanceKey||common.createNewInstanceKey();
            }
            state
                .instances
                .set(newInstanceKey, {
                    gaeaKey: params.gaeaKey,
                    data: params.data||{
                        props: null
                    },
                    slots: {},
                    parentInstanceKey: params.parentInstanceKey,
                    preGaeaKey: params.preGaeaKey,
                    vm: null
                });
            // 先执行 callback  挂载 vm 再执行 修改属性样式
            //note 更新实例数组顺序，让新添加进来的数组放在父数组下面
            debugger;
            let instanceArr=[...state.instances];
            let parentIndex=0;
            try {
                state.instances.forEach(function(v,k) {
                    console.log(v); //这样就会分别将name遍历出来
                    parentIndex++;
                    if(k==params.parentInstanceKey){
                        //note 说明得到父元素
                        throw new Error("EndIterative");
                    }
                });
            } catch(e) {
                //note 只有在捕获到父元素的情况下且是处于拖动的情况下，才会挪动数组
                if(state.isDrag||params.isDrag){
                    debugger;
                    state.instances=[...state.instances];
                    let index=state.instances.length-1;
                    parentIndex+=params.indexPosition;
                    //note 修改数组位置
                    if(index>parentIndex){
                        let strInstance=[];
                        let myTest=state.instances;
                        //    strInstance=myTest.concat();
                        state.instances.splice(parentIndex,0,state.instances[index]);
                        state.instances.splice(index+1,1)

                    }
                    else{
                        //如果当前元素在拖动目标位置的上方，先将当前元素从数组拿出，数组长度-1，我们直接给数组拖动目标位置+1的地方新增一个和当前元素值一样的元素，
                        //这时，数组len不变，我们再把数组之前的那个拖动的元素删除掉，下标还是index
                        state.instances.splice(parentIndex+1,0,state.instances[index]);
                        state.instances.splice(index,1)
                    }

                    state.instances = new Map(state.instances);
                    if (params.cb) {
                        params
                            .cb
                            .call(null, newInstanceKey, { isInsert:true,childIndex:params.indexPosition});
                    }
                }else{
                    state.instances = new Map(state.instances);
                    if (params.cb) {
                        params
                            .cb
                            .call(null, newInstanceKey, { isInsert:false});
                    }
                }
                if(e.message!="EndIterative") throw e;
            };


            if(params.gaeaKey=="gaea-form"){
                state.currentFormInstanceKey=newInstanceKey;
            }
            if(params.gaeaKey=="gaea-box"){
                state.currentBoxInstanceKey=newInstanceKey;
            }

            // 然后再执行修改样式
            if (params.parentInstanceKey !== null) {
                const parentInstance = state
                    .instances
                    .get(params.parentInstanceKey);
                if (!parentInstance.slots[params.slotName]) {
                    parentInstance.slots[params.slotName] = [];
                }
                if(state.isDrag) {
                    parentInstance
                        .slots[params.slotName]
                        .splice(params.indexPosition, 0, newInstanceKey);
                }else{
                    parentInstance
                        .slots[params.slotName]
                        .splice(parentInstance
                            .slots[params.slotName].length, 0, newInstanceKey);
                }
                // 如果父级和自身都是 gaea-container，且父级是 display:flex，那么子元素默认 flexDirection 与父级元素相反
                //note 处理业务逻辑
                state.currentEditInstanceKey=newInstanceKey;
                state.parentEditInstanceKey= params.parentInstanceKey;
                if (parentInstance.gaeaKey === 'gaea-container' && params.gaeaKey === 'gaea-container') {
                }
            }
        },
        setInstanceProps (state, {vm, key, value}) {
            if (Object.prototype.toString.call(value) === '[object Object]') {
                let obj = _.get(vm.$data, key);
                let newObj=Object.assign(obj, value)
                _.set(vm.$data, key, newObj);
            } else {
                _.set(vm.$data, key, value);
            }
            vm.$forceUpdate();
        },
        setRootInstanceKey (state, key) {
            state.rootInstanceKey = key;
        },
        setDomInstance (state, {key, instance}) {
            state
                .instanceDoms
                .set(key, instance);
        },
        setCurrentHoverInstanceKey (state, instanceKey) {
            // debugger;
        //    console.log("currentHoverInstanceKey:"+instanceKey);
            state.currentHoverInstanceKey = instanceKey;
        },
        moveInstance (state, {sourceTargetKey, targetParentKey, targetIndex, fromSlotName, toSlotName}) {
            debugger;
            if(!sourceTargetKey){
                return;
            }
            sourceTargetKey=state.currentEditInstanceKey;
            const sourceTargetInstance = state
                .instances
                .get(sourceTargetKey);
            const sourceParentInstance = state
                .instances
                .get(sourceTargetInstance.parentInstanceKey);
            const targetParentInstance = state
                .instances
                .get(targetParentKey);
            if (sourceTargetInstance.parentInstanceKey !== targetParentKey) { // 跨越层级
                // 修改拖拽元素的 parentMapUniqueKey
                sourceTargetInstance.parentInstanceKey = targetParentKey;

                // 拖拽目标添加 instance
                if (!targetParentInstance
                    .slots[toSlotName]) {
                    targetParentInstance
                        .slots[toSlotName] = [];
                }
                targetParentInstance
                    .slots[toSlotName]
                    .splice(targetIndex, 0, sourceTargetKey);

                // 拖拽源删除 instance
                sourceParentInstance.slots[fromSlotName] = sourceParentInstance
                    .slots[fromSlotName]
                    .filter(childKey => childKey !== sourceTargetKey);
                this.commit('viewport/dealCurLevelAndTargetLevel', {
                    currentInstance: sourceTargetKey,
                    targetInstance: targetParentKey
                });
            } else { // 同层级
                this.commit('viewport/horizontalMoveInstance', {
                    parentKey: targetParentKey,
                    beforeIndex: sourceParentInstance
                        .slots[fromSlotName]
                        .findIndex(childKey => childKey === sourceTargetKey),
                    afterIndex: targetIndex
                });
            }
            // 触发 VueX 对map的检查
            state.instances = new Map(state.instances);
        },
        /**
         * 同层级拖拽，不需要主动调用，直接调用 moveInstance 即可
         */
        horizontalMoveInstance (state, {parentKey, beforeIndex, afterIndex, slotName}) {
            console.log();
            const parentInstance = state
                .instances
                .get(parentKey);
            if (beforeIndex < afterIndex) {
                // 从左到右
                for (let index = beforeIndex; index < afterIndex; index++) {
                    const beforeUniqueKey = parentInstance.slots[slotName][index];
                    const afterUniqueKey = parentInstance.slots[slotName][index + 1];
                    parentInstance.slots[slotName][index] = afterUniqueKey;
                    parentInstance.slots[slotName][index + 1] = beforeUniqueKey;
                }
            } else {
                // 从右到左
                for (let index = beforeIndex; index > afterIndex; index--) {
                    const beforeUniqueKey = parentInstance.slots[slotName][index];
                    const afterUniqueKey = parentInstance.slots[slotName][index - 1];
                    parentInstance.slots[slotName][index] = afterUniqueKey;
                    parentInstance.slots[slotName][index - 1] = beforeUniqueKey;
                }
            }
            // 触发 VueX 对map的检查
            state.instances = new Map(state.instances);

            /*    this.commit('viewport/dealCurSecontLevel', {
                    currentInstance: state.currentEditInstanceKey,
                    targetInstance: parentKey,
                    beforeIndex, afterIndex
                });*/
        },
        setDragInfo (state, {mapUniqueKey, index}) {
            const newInfo = state.currentDragInfo.info;
            newInfo.targetInstanceKey = mapUniqueKey;
            newInfo.targetIndex = index;
        },
        registerOuterDrag (state, dragParentDom) {
            // 上次拖拽的位置
            debugger;
            let lastDragStartIndex = -1;
            Sortable.default.create(dragParentDom, {
                animation: 50,
                // 放在一个组里,可以跨组拖拽
                group: {
                    name: 'gaea-container',
                    pull: 'clone',
                    put: false
                },
                sort: false,
                delay: 0,
                filter:".collapse-header",
                // draggable:".isDrag",
                onStart: (event) => {
                    lastDragStartIndex = event.oldIndex;
                    console.log("---onStart>");
                    console.log(event.item);
                    console.log(event.item.dataset);
                    console.log(event.item.dataset.gaeaKey);
                    var ele=event.item;
                    console.log(ele.attributes);
                    var dataEle={};
                    console.log("test22");
                    var attrs = ele.attributes,//元素的属性集合
                        dataset = {}, name, matchStr;
                    for(var i = 0;i<attrs.length;i++){ //是否是data- 开头
                        matchStr = attrs[i].name.match(/^data-(.+)/);
                        if(matchStr){ //data-auto-play 转成驼峰写法 autoPlay
                            name = matchStr[1].replace(/-([\da-z])/gi,function(all,letter){
                                return letter.toUpperCase(); });
                            dataset[name] = attrs[i].value;
                        }
                    }
                    dataEle= dataset;
                    // }
                    console.log("11--->");
                    console.log(dataEle);
                    console.log(dataEle.gaeaKey);
                    console.log("00--->");
                    if (dataEle.source) {
                        console.log("---source>"+dataEle.source);
                        // this.startDrag({     type: 'combo',     dragStartParentElement:
                        // dragParentDom,     dragStartIndex: event.oldIndex ,     comboInfo: { source:
                        // dataEle.source     } })
                    } else if (dataEle.gaeaKey) {
                        console.log("---gaeaKey>"+dataEle.gaeaKey);
                        state.dragStartDataReady = false;
                        this.commit('viewport/startDrag', {
                            type: 'new',
                            dragStartParentDom: dragParentDom,
                            dragStartIndex: event.oldIndex,
                            info: {
                                gaeaKey: dataEle.gaeaKey,
                                props: dataEle.props,
                                preGaeaKey: dataEle.preGaeaKey
                            }
                        });
                        // 开始拖拽完毕
                        console.log("---over>");
                        state.dragStartDataReady = true;
                    }
                },
                onEnd: (event) => {
                    debugger;
                    this.commit('viewport/endDrag');
                    // 因为是 clone 方式, 拖拽成功的话元素会重复, 没成功拖拽会被添加到末尾 所以先移除 clone 的元素（吐槽下, 拖走的才是真的, 留下的才是
                    // clone 的） 有 parentNode, 说明拖拽完毕还是没有被清除, 说明被拖走了, 因为如果没真正拖动成功, clone 元素会被删除
                    if (event.clone.parentNode) {
                        //note 如果拖走了,把已经拖走的元素删除,只显示转换后的元素
                        if(event.item.parentNode){
                            event.item.parentNode.removeChild(event.item);
                        }

                    } else {
                        //note 没拖走, 只是晃了一下, 不用管了
                    }


                }
            });
        },
        //note 创建元素和实例
        createInstanceEle(newInfo){
            this.commit('viewport/addInstance', {
                gaeaKey: newInfo.gaeaKey,
                parentInstanceKey:newInfo.parentInstanceKey,
                indexPosition: 0,
                preGaeaKey: newInfo.preGaeaKey,
                slotName:newInfo.slotName,

                cb: newInstanceKey => {
                    debugger;
                    if (onDragAdd) {
                        // e --event parentInstanceKey  --父instanceKey gaeaKey  -->component type
                        // newInstanceKey  -> new instace Key
                        onDragAdd.call(this, null,{}, newInfo.parentInstanceKey, newInfo.gaeaKey, newInstanceKey, newInfo.slotName);
                    }
                }
            });
        },
        registerInnerDrag (state, {
            parentInstanceKey,
            dragParentDom,
            params,
            groupName = 'gaea-container',
            onDragAdd
        }) {

            const instance = state
                .instances
                .get(parentInstanceKey);
            let oldObj={

                animation: 50,
                // 放在一个组里,可以跨组拖拽
                group: {
                    name: groupName,
                    pull: true,
                    put: true
                },
                onStart: (event) => {
                    console.log(event);
                    console.log("onStart");
                    console.log(parentInstanceKey);
                    console.log(event.newIndex);
                    let slotName = event.from.dataset.slotName;
                    let curInstance= state
                        .instances
                        .get(instance.slots[slotName][event.oldIndex]);
                    let newObj=Object.assign({}, curInstance);
                    state.saveDragObj=newObj;

                    this.commit('viewport/startDrag', {
                        type: 'viewport',
                        dragStartParentDom: dragParentDom,
                        dragStartIndex: event.oldIndex,
                        info: {
                            instanceKey: instance.slots[slotName][event.oldIndex]
                        }
                    });
                },
                onEnd: (event) => {
                    console.log("onEnd");
                    this.commit('viewport/endDrag');

                    // 在 viewport 中元素拖拽完毕后, 为了防止 outer-move-box 在原来位置留下残影, 先隐藏掉
                    this.commit('viewport/setCurrentHoverInstanceKey', null);
                },
                onAdd: (event) => {
                    console.log(state.instances);
                    console.log("onAdd");
                    // 如果数据还没有 ready，很尴尬，什么都没有发生 此时一定是 new，不用担心 dom 节点脏掉
                    /*  if (!state.dragStartDataReady) {
                          return;
                      }*/
                    debugger;
                    if(event.newIndex<2){
                        event.item.parentNode.removeChild(event.item);
                        return;
                    }
                    switch (state.currentDragInfo.type) {
                        case 'new':
                            // 是新拖进来的, 不用管, 因为工具栏会把它收回去 为什么不删掉? 因为这个元素不论是不是 clone, 都被移过来了, 不还回去 react 在更新
                            // dom 时会无法找到
                            const newInfo = state.currentDragInfo.info;
                            const slotName = event.to.dataset.slotName;

                            this.commit('viewport/addInstance', {
                                gaeaKey: newInfo.gaeaKey,
                                parentInstanceKey,
                                indexPosition: event.newIndex,
                                preGaeaKey: newInfo.preGaeaKey,
                                slotName,
                                cb: (newInstanceKey,dataObj)=> {
                                    debugger;
                                    if (onDragAdd) {
                                        // e --event parentInstanceKey  --父instanceKey gaeaKey  -->component type
                                        // newInstanceKey  -> new instace Key
                                        onDragAdd.call(this, null,function(){return {}}, parentInstanceKey, newInfo.gaeaKey, newInstanceKey, slotName,dataObj);
                                    }
                                }
                            });
                            break;
                        case 'viewport':
                            // 设置新增时拖拽源信息
                            this.commit('viewport/setDragInfo', {
                                mapUniqueKey: parentInstanceKey,
                                index: event.newIndex
                            });
                            break;
                        case 'combo':
                            // this.addComboComponentBySource(mapUniqueKey,
                            // this.viewport.currentDragComponentInfo.comboInfo.source, event.newIndex )
                            // TODO 发布新增组合事件 this.props.viewport.saveOperate({     type: 'addCombo',
                            // mapUniqueKey,     addCombo: {         parentMapUniqueKey:
                            // this.props.mapUniqueKey,         index: event.newIndex , componentInfo:
                            // component     } })
                            break;
                    }
                },
                onUpdate: (event) => {
                    console.log("onUpdate");
                    let slotName = event.from.dataset.slotName;
                    if(event.oldIndex<2||event.newIndex<2){

                        let currentChild= state.instanceDoms.get(state.currentEditInstanceKey);
                        console.log(currentChild);
                        let parent = currentChild.parentNode;
                        console.log(parent);
                        let myParent = $('.ty-content-element-form').find('.formDiv').toArray();
                        console.log(myParent);
                        let oldIndex=event.oldIndex;
                        let newIndex=event.newIndex;
                        /*//如果当前元素在拖动目标位置的上方，先将当前元素从数组拿出，数组长度-1，我们直接给数组拖动目标位置+1的地方新增一个和当前元素值一样的元素，
                        //这时，数组len不变，我们再把数组之前的那个拖动的元素删除掉，下标还是index
                        state.instances.splice(parentIndex+1,0,state.instances[index]);
                        state.instances.splice(index,1)
                         从2拖到3
                        1      1    1
                        2      3    (2)
                        3      (2)   3
                        4       4    (2)
                        5       5     4
                                       5
                          从4拖到2
                         1      1       1
                        2      （4）    (4)
                        3      2         2
                        4       3        3
                        5       5        4
                                          5

                        */

                        if(event.oldIndex<event.newIndex){
                            //note 往后拖动，比如从2 拖动4
                            myParent.splice(oldIndex,0,myParent[newIndex]);
                            myParent.splice(newIndex+1,1);
                        }else{
                            myParent.splice(oldIndex+1,0,myParent[newIndex]);
                            myParent.splice(newIndex,1);
                        }


                        /*  var temp;
                          // 1 3对调
                          temp = myParent[newIndex];
                          myParent[oldIndex] = myParent[newIndex];
                          myParent[newIndex] = temp;
                          console.log(myParent);*/
                        $('.ty-content-element-form').html(myParent)
                        return;
                    }
                    //  同一个父级下子元素交换父级 // 取消 srotable 对 dom 的修改, 让元素回到最初的位置即可复原
                    this.commit('viewport/horizontalMoveInstance', {
                        parentKey: parentInstanceKey,
                        beforeIndex: event.oldIndex,
                        afterIndex: event.newIndex,
                        slotName
                    });
                },
                onRemove: (event) => {
                    debugger;
                    console.log("onRemove");
                    // onEnd 在其之后执行，会清除拖拽目标的信息 减少了一个子元素，一定是发生在 viewport 区域元素发生跨父级拖拽时
                    let toSlotName = event.to.dataset.slotName;
                    let fromSlotName = event.from.dataset.slotName;
                    const dragTargetKey = state
                        .instances
                        .get(parentInstanceKey)
                        .slots[toSlotName][state.currentDragInfo.dragStartIndex];
                    const dragViewportInfo = state.currentDragInfo.info;

                    let curInstance= state
                        .instances
                        .get(dragTargetKey);
                    // if(typeof(curInstance)!="undefined"&&curInstance.vm.level>2){
                    if(typeof(curInstance)=="undefined"){
                        return;
                    }
                    this.commit('viewport/moveInstance', {
                        sourceTargetKey: dragTargetKey,
                        targetParentKey: dragViewportInfo.targetInstanceKey,
                        targetIndex: dragViewportInfo.targetIndex,
                        fromSlotName,
                        toSlotName
                    });
                }
            }
            let newObj = Object.assign(params, oldObj);
            Sortable.default.create(dragParentDom,newObj);


            //note 删除当前拖拽的组件
            this.commit('viewport/dealLevel', state);
        },
        getInstancePath (state, {instanceKey, cb}) {
            const finderPath = [state.currentEditInstanceKey];
            if (state.currentEditInstanceKey === null) {
                if (cb) {
                    let result = [];
                    cb(result);
                }
                return;
            }
            let instance = state
                .instances
                .get(state.currentEditInstanceKey);
            // 如果已经是根元素, 直接返回空数组
            if (instance.parentInstanceKey === null) {
                if (cb) {
                    let result = [state.rootInstanceKey];
                    cb(result);
                }
                return;
            }

            // 直到父级是根元素为止
            while (state.instances.get(instance.parentInstanceKey).parentInstanceKey !== null) {
                finderPath.unshift(instance.parentInstanceKey);
                instance = state
                    .instances
                    .get(instance.parentInstanceKey);
            }
            finderPath.unshift(state.rootInstanceKey);
            if (cb) {
                cb(finderPath);
            }
        },
        setCurrentEditInstanceKey (state, instanceKey) {
            // 如果和当前正在编辑元素相同，不做操作
            if (state.currentEditInstanceKey === instanceKey) {
                return;
            }
            // 修改 mapUniqueKey
            state.currentEditInstanceKey = instanceKey;
        },
        setPagePriviewData(state,pageObjData){
            //设置页面数据
            state.pagePriviewData = pageObjData;
        }
    },
    actions: {}
};
//note 自定义mutation
let selfMutation={
    //note 显示弹层


    updateInputData(state){
        let currentInstance= state.instances.get(state.currentEditInstanceKey);

        for(let prop in currentInstance.data.property){
            currentInstance.data.property[prop]="哈哈哈";
        }
        for(let prop in currentInstance.data.property){
            currentInstance.data.property[prop]="哈哈哈";
        }
        state.instances = new Map(state.instances);
        /**/
        /* this.commit('viewport/setInstanceProps', {
                                      vm: currentInstance.vm,
                                      key: 'property',
                                      value: {
                                          label: '哈哈哈'
                                      }
                                  });*/
    },
    //NOTE 修改全局值
    updateData(state,element){


        /* state.instances = new Map(state.instances);
         return;*/

        let allInstance= state.instances;
        let localInstance= state.localInstances;
        localInstance= [...localInstance];
        allInstance= [...allInstance];
        localInstance.splice(0,0,allInstance[0])

        let _this=this;
        for(let key=0;key<localInstance.length;key++){
            let keyName=localInstance[key][0];
            let val=localInstance[key][1];
            if(keyName!="gaea_instance_1"){
                //给我们的实例赋值
                //      allInstance[key][1].data=new Object(localInstance[key][1].data);
                // allInstance[key][1].data.property.label="哈哈哈";

                // allInstance[key][1].data.property=localInstance[key][1].data.property;
                for(let prop in allInstance[key][1].data){
                    allInstance[key][1].data[prop]=localInstance[key][1].data[prop];
                }
                /*for(let prop in localInstance[key][1].data.property){
                    allInstance[key][1].data.property[prop]=localInstance[key][1].data[prop];
                }*/
            }
        }
        state.instances=allInstance;
        state.instances = new Map(state.instances);


        /* for(let key=0;key<localInstance.length;key++){
             let keyName=localInstance[key][0];
             let val=localInstance[key][1];
             if(keyName!="gaea_instance_1"){
                 //给我们的实例赋值
                 //  allInstance[key][1].data.property.label="哈哈哈";
                 allInstance[key][1].vm.$forceUpdate();
             }
         }*/

        /*currentInstance.data.property.label="哈哈哈";
        state.instances = new Map(state.instances);*/
        /*this.commit('viewport/setInstanceProps', {
                                     vm: currentInstance.vm,
                                     key: 'property',
                                     value: {
                                         label: '哈哈哈'
                                     }
                                 });*/

    },
    //NOTE 存储元素 localInstances
    updateInstances(state,element){

        state.instances=state.localInstances;
        state.instances = new Map(state.instances);
    },
    //NOTE 存储元素 localInstances
    saveLocalElement(state,element){
        state.localElement=element;
    },
    //NOTE 存储实例 localInstances
    saveLocalInstances(state,instances){
        debugger;
        let localInstances= [...state.instances];

        //let localInstances=_.cloneDeep(myarr);
        localInstances.splice(0,1);
        for(let key=0;key<localInstances.length;key++){
            delete localInstances[key][1].vm;
            // val.data.property.value=val.data.property.label;
        }
        console.log(localInstances); // [ 1, 2, 3 ]  openModalTitle
        let templateJSON=JSON.stringify(localInstances);
        //  eventbus.$emit("openModalTitle",localInstances);
        console.log(templateJSON);
        return;
        let toServerParams = {
            itemNo:localStorage.itemNo,
            itemStep:localStorage.itemStep,
            jsonType:1,
            jsonStr:templateJSON
        };
        Service.saveTemplateOrJsonToServer(toServerParams).then((res) => {
            //note 刚才保存完了json，现在要保持模板
            localStorage.status="1";
            eventbus.$emit("openSuccDialog");
            httpLoading.closeLoading();
        })

        //note 发送网络请求,把保存的模板提交给后台
        state.localInstances = new Map([]);
    },
    /*
     Note 增加删除单选内容选项
    */
    delRadioEventArr(state,childObj){

        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.radioArr) {
            currentInstance.data.radioArr = [];
        }
        // 为事件新增一项
        currentInstance.data.radioArr.splice(childObj.index,1);
        state.instances = new Map(state.instances);
    },
    addRadioEventArr(state){
        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.radioArr) {
            currentInstance.data.radioArr = [];
        }
        // 为事件新增一项
        currentInstance.data.radioArr.push({
            label: "选项"+(currentInstance.data.radioArr.length+1),
            value: "选项"+(currentInstance.data.radioArr.length+1)
        });
        state.instances = new Map(state.instances);
    },
    /*
Note 删除增加  元素联动检查是否隐藏/显示
*/
    addShowFlagEventArr(state){
        debugger;
        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.extend.showFlag) {
            currentInstance.data.extend.showFlag = [];
        }
        // 为事件新增一项
        currentInstance.data.extend.showFlag.push({
            key: "",
            value: ""
        });
        state.instances = new Map(state.instances);
    },
    delShowFlagEventArr(state,childObj){

        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.extend.showFlag) {
            currentInstance.data.extend.showFlag = [];
        }
        // 为事件新增一项
        currentInstance.data.extend.showFlag.splice(childObj.index,1);
        state.instances = new Map(state.instances);
    },
    /*
 Note 删除增加校验
*/
    delValidateEventArr(state,childObj){

        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.validateArr) {
            currentInstance.data.validateArr = [];
        }
        // 为事件新增一项
        currentInstance.data.validateArr.splice(childObj.index,1);
        state.instances = new Map(state.instances);
    },
    addValidateEventArr(state){

        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.validateArr) {
            currentInstance.data.validateArr = [];
        }
        if(currentInstance.gaeaKey=="gaea-input"||currentInstance.gaeaKey=="gaea-textarea"){
            // 为事件新增一项
            currentInstance.data.validateArr.push({
                required: false,
                message: "不能为空",
                type: "",
                trigger: "",
                dot: "",
                range: 0,
                unit: "",
            },{
                message: "不能为空",
                maxLength:100,
                type: "inputLength",
                trigger: "blur",
                dot: "",
                range: 0,
                unit: "",
            });
        }else{
            // 为事件新增一项
            currentInstance.data.validateArr.push({
                required: false,
                message: "不能为空",
                type: "",
                trigger: "",
                dot: "",
                range: 0,
                unit: "",
            });
        }

        state.instances = new Map(state.instances);
    },
    addValidateEventChildArr(state,childObj){
        debugger;
        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.validateArr) {
            currentInstance.data.validateArr = [];
        }
        if (!currentInstance.data.validateArr[childObj.index].requireKeyValues) {
            currentInstance.data.validateArr[childObj.index].requireKeyValues = [];
        }
        // 为事件新增一项
        //currentInstance.data.validateArr[childObj.index].requireKeyValues=[];
        currentInstance.data.validateArr[childObj.index].requireKeyValues.push({
            //  dependValue: "",
            //changeValue: "",
            key:"",
            values: ""
        });
        state.instances = new Map(state.instances);
    },
    delValidateEventChildArr(state,childObj){

        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.validateArr) {
            currentInstance.data.validateArr = [];
        }
        // 为事件新增一项
        currentInstance.data.validateArr[childObj.parentIndex].requireKeyValues.splice(childObj.index,1);
        state.instances = new Map(state.instances);
    },
    /*
  Note checkBox二位数组 增加 删除
*/
    addCheckEventArr(state){
        debugger;
        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.mockData) {
            currentInstance.data.mockData = [];
        }
        // 为事件新增一项
        currentInstance.data.mockData.push({
            label: "",
            value: "",
            show: false,
            radioList:[]
        });
        state.instances = new Map(state.instances);
    },
    delCheckEventArr(state,childObj){
        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.mockData) {
            currentInstance.data.mockData = [];
        }
        // 为事件新增一项
        currentInstance.data.mockData.splice(childObj.index,1);
        state.instances = new Map(state.instances);
    },
    addCheckChildArr(state,childObj){

        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.mockData[childObj.index].radioList) {
            currentInstance.data.mockData[childObj.index].radioList = [];
        }
        // 为事件新增一项
        currentInstance.data.mockData[childObj.index].radioList.push({
            "name": "",
            "isSelected": false,
            "value": ""
        });
        state.instances = new Map(state.instances);
    },
    delCheckChildArr(state,childObj){
        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.mockData) {
            currentInstance.data.mockData = [];
        }
        // 为事件新增一项
        currentInstance.data.mockData[childObj.parentIndex].radioList.splice(childObj.index,1);
        state.instances = new Map(state.instances);
    },
    /*
   Note 步骤增加 删除
 */
    addLinkItemsEventArr(state){
        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.items) {
            currentInstance.data.items = [];
        }
        // 为事件新增一项
        currentInstance.data.items.push({
            label: "",
            prop: "",
            isShow: "",
        });
        state.instances = new Map(state.instances);
    },
    addLinkOptionsEventArr(state,childObj){

        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.items[childObj.index].options) {
            currentInstance.data.items[childObj.index].options = [];
        }
        // 为事件新增一项
        currentInstance.data.items[childObj.index].options.push({
            name: "",
            value: 0,
            isSelected:false
        });
        state.instances = new Map(state.instances);
    },
    addLinkExactEventArr(state,childObj){

        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.items[childObj.index].exact) {
            currentInstance.data.items[childObj.index].exact = [];
        }
        // 为事件新增一项
        currentInstance.data.items[childObj.index].exact.push({
            type: "",
        });
        state.instances = new Map(state.instances);
    },
    delLinkItemsEventArr(state,childObj){

        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.items) {
            currentInstance.data.items = [];
        }
        // 为事件新增一项
        currentInstance.data.items.splice(childObj.index,1);
        state.instances = new Map(state.instances);
    },
    delLinkExactEventChildArr(state,childObj){

        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.items) {
            currentInstance.data.items = [];
        }
        // 为事件新增一项
        currentInstance.data.items[childObj.parentIndex].exact.splice(childObj.index,1);
        state.instances = new Map(state.instances);
    },
    delLinkOptionsEventChildArr(state,childObj){

        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.linkageChangeValue) {
            currentInstance.data.extend.linkageChangeValue = [];
        }
        // 为事件新增一项
        currentInstance.data.items[childObj.parentIndex].options.splice(childObj.index,1);
        state.instances = new Map(state.instances);
    },
    /*
    Note 步骤增加 删除
  */
    delStepsEventArr(state,childObj){

        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.steps) {
            currentInstance.data.steps = [];
        }
        // 为事件新增一项
        currentInstance.data.steps.splice(childObj.index,1);
        state.instances = new Map(state.instances);
    },
    addStepsEventArr(state){

        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.steps) {
            currentInstance.data.steps = [];
        }
        // 为事件新增一项
        currentInstance.data.steps.push({
            title: ""
        });
        state.instances = new Map(state.instances);
    },

    /*
   Note 调用远程地址 增加请求参数
   */
    addTableDynamicArr(state){
        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.property.data) {
            currentInstance.data.property.data={};
            if (!currentInstance.data.property.data.paramsList) {
                currentInstance.data.property.data.paramsList = [];
            }
        }
        // 为事件新增一项
        currentInstance.data.property.data.paramsList.push({
            label: "",
            value: ""
        });
        state.instances = new Map(state.instances);
    },
    updateTableDynamicArr(state){
        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.property.data) {
            currentInstance.data.property.data={};
            if (!currentInstance.data.property.data.paramsList) {
                currentInstance.data.property.data.paramsList = [];
            }
            if (!currentInstance.data.property.data.params) {
                currentInstance.data.property.data.params = {};
            }
        }
        if(currentInstance.data.property.data.paramsList){
            let paramObj={};
            currentInstance.data.property.data.paramsList.forEach(function(el,index){
                paramObj[el.label]=el.value;
            });
            currentInstance.data.property.data.params=paramObj;
        }
        debugger;
        state.instances = new Map(state.instances);
    },
    delDynamEventArr(state,childObj){
        debugger;
        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.property.dynamic) {
            currentInstance.data.property.dynamic={};
            if (!currentInstance.data.property.dynamic.paramsList) {
                currentInstance.data.property.dynamic.paramsList = [];
            }
        }
        // 为事件新增一项
        currentInstance.data.property.dynamic.paramsList.splice(childObj.index,1);
        state.instances = new Map(state.instances);
    },
    addDynamicArr(state){
        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.property.dynamic) {
            currentInstance.data.property.dynamic={};
            if (!currentInstance.data.property.dynamic.paramsList) {
                currentInstance.data.property.dynamic.paramsList = [];
            }
        }
        // 为事件新增一项
        currentInstance.data.property.dynamic.paramsList.push({
            label: "",
            value: ""
        });
        state.instances = new Map(state.instances);
    },
    updateDynamicArr(state){
        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.property.dynamic) {
            currentInstance.data.property.dynamic={};
            if (!currentInstance.data.property.dynamic.paramsList) {
                currentInstance.data.property.dynamic.paramsList = [];
            }
            if (!currentInstance.data.property.dynamic.params) {
                currentInstance.data.property.dynamic.params = {};
            }
        }
        if(currentInstance.data.property.dynamic.paramsList){
            let paramObj={};
            currentInstance.data.property.dynamic.paramsList.forEach(function(el,index){
                paramObj[el.label]=el.value;
            });
            currentInstance.data.property.dynamic.params=paramObj;
        }
        debugger;
        state.instances = new Map(state.instances);
    },
    /*
     Note 联动增加 删除
     */
    delLinkEventArr(state,childObj){

        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.extend.linkageChangeValue) {
            currentInstance.data.extend.linkageChangeValue = [];
        }
        // 为事件新增一项
        currentInstance.data.extend.linkageChangeValue.splice(childObj.index,1);
        state.instances = new Map(state.instances);
    },
    delLinkEventChildArr(state,childObj){
        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.extend.linkageChangeValue) {
            currentInstance.data.extend.linkageChangeValue = [];
        }
        // 为事件新增一项
        currentInstance.data.extend.linkageChangeValue[childObj.parentIndex].values.splice(childObj.index,1);
        state.instances = new Map(state.instances);
    },
    addLinkEventChildArr(state,childObj){

        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.extend.linkageChangeValue) {
            currentInstance.data.extend.linkageChangeValue = [];
        }
        if (!currentInstance.data.extend.linkageChangeValue[childObj.index].values) {
            currentInstance.data.extend.linkageChangeValue[childObj.index].values = [];
        }
        // 为事件新增一项
        // currentInstance.data.extend.linkageChangeValue[childObj.index].values=[];
        currentInstance.data.extend.linkageChangeValue[childObj.index].values.push({
            //  dependValue: "",
            //changeValue: "",
            changeParam:"",
            changeAttrs: {
                "readonly": false,
                "clearable": false
            }
        });
        state.instances = new Map(state.instances);
    },
    addLinkEventArr(state){

        let currentInstance= state.instances.get(state.currentEditInstanceKey);
        if (!currentInstance.data.extend.linkageChangeValue) {
            currentInstance.data.extend.linkageChangeValue = [];
        }
        // 为事件新增一项
        currentInstance.data.extend.linkageChangeValue.push({
            changeKey: "",
            type: "",
            isValue:false,
            noChangeExist:false
        });
        state.instances = new Map(state.instances);
    },
    //note 删除
    deleteLevel1Data(state){
        debugger;
        return;
        //NOTE 获取所有级别为1的（排除根节点），全部删除
        let localInstances= [...state.instances];
        let myArr=localInstances.splice(0,1);
        myArr[0][1].slots.default=[];
        state.instances = new Map(myArr);

        this.commit('viewport/deleteDoomData',myArr[0][0]);

        //note 初始化模板的值
        //  this.commit('viewport/deleteData',"gaea_instance_1");//note 这个是contain
        eventbus.$emit("initTemplateInstance");
    },
    //note 清空所有doom
    deleteDoomData(state,currentKey){
        debugger;
        let localInstancesDoms= [...state.instanceDoms];
        for(let i=0;i<localInstancesDoms.length;i++){
            let myKey= localInstancesDoms[i][0];
            if(myKey!=currentKey){
                let currentChild= state.instanceDoms.get(myKey);
                let parent = currentChild.parentNode;
                parent.removeChild(currentChild);
                state.instanceDoms.delete(myKey);
            }

        }

    },
    deleteData(state,currentKey){
        debugger;
        let currentChild= state.instanceDoms.get(currentKey);
        $(currentChild).hide();
        let parent = currentChild.parentNode;
        state.moveInstance.push(currentKey)
        //parent.removeChild(currentChild);
        return;
        state.instanceDoms.delete(currentKey);
        //取出当前删除元素的父元素,并在父元素中删除对应的元素
        console.log(state.instances.get(currentKey));
        let parentInstanceKey =  state.instances.get(currentKey).parentInstanceKey;
        if(parentInstanceKey){
            let childArr = state.instances.get(parentInstanceKey).slots.default;
            _.pullAll(childArr,[currentKey]);
        }
        let instancesObj = state.instances.get(currentKey);
        //连级删除自身和子元素
        state.instances.delete(currentKey);
        state.instances = new Map(state.instances);
    },
    deleteDataArr(state){
        debugger;

        console.log(state.instances);
        state.moveInstance.forEach((currentKey,index)=>{
            state.instanceDoms.delete(currentKey);
            //取出当前删除元素的父元素,并在父元素中删除对应的元素
            console.log(state.instances.get(currentKey));
            let parentInstanceKey =  state.instances.get(currentKey).parentInstanceKey;
            if(parentInstanceKey){
                let childArr = state.instances.get(parentInstanceKey).slots.default;
                _.pullAll(childArr,[currentKey]);
            }
            let instancesObj = state.instances.get(currentKey);
            //连级删除自身和子元素
            state.instances.delete(currentKey);
            state.instances = new Map(state.instances);
        });
       console.log(state.instances);
    },
    deleteAll(state,data){
        if(data.instancesObj.slots.default&&data.instancesObj.slots.default.length>0){
            data.instancesObj.slots.default.forEach((item)=>{
                let instancesObj = state.instances.get(item);
                this.commit('viewport/deleteAll',{instancesObj:instancesObj,delObj:item});
            });
        }
        state.instances.delete(data.delObj);
    }
}
let newObj=Object.assign(viewport.mutations, selfMutation);
viewport.mutations=newObj;
export default viewport;
