<template>
  <ul class="contentmenu"
      id="avue-data-menu">
    <li class="contentmenu__item"
        @click="contain.handleParams('lock')">
      <el-icon>
        <el-icon-lock />
      </el-icon>
      {{contain.activeObj.lock?'解锁':'锁定'}}
    </li>
    <li class="contentmenu__item"
        @click="contain.handleParams('display')">
      <el-icon>
        <el-icon-view />
      </el-icon>
      {{contain.activeObj.display?'显示':'隐藏'}}
    </li>
    <li class="contentmenu__item"
        @click="contain.isFolder?handleLogout():handleCompose()">
      <el-icon>
        <el-icon-document-copy />
      </el-icon>
      {{contain.isFolder?'解散':'组合'}}
    </li>
    <li class="contentmenu__item"
        @click="handleDel()">
      <el-icon>
        <el-icon-delete />
      </el-icon>
      删除
    </li>
    <li class="contentmenu__item"
        v-if="!contain.isFolder">
      <el-icon>
        <el-icon-pointer />
      </el-icon>
      交互
      <el-icon class="contentmenu__list--icon">
        <el-icon-caret-right />
      </el-icon>
      <ul class="contentmenu contentmenu__list">
        <li class="contentmenu__item"
            v-if="contain.validProp('dataList')"
            @click="handleOpen('data')">
          <el-icon>
            <el-icon-document-copy />
          </el-icon>
          添加数据
        </li>
        <li class="contentmenu__item"
            @click="handleOpen('transfer')">
          <el-icon>
            <el-icon-edit />
          </el-icon>
          添加交互
        </li>
        <li class="contentmenu__item"
            @click="handleOpen('animated')">
          <el-icon>
            <el-icon-mouse />
          </el-icon>
          添加动画
        </li>
        <li class="contentmenu__item"
            @click="handleOpen('default')">
          <el-icon>
            <el-icon-mouse />
          </el-icon>
          其他配置
        </li>

        <li class="contentmenu__item"
            v-if="contain.validProp('dataList')"
            @click="handleCopyData()"><i class="iconfont icon-copy"></i>
          复制数据配置
        </li>
        <li class="contentmenu__item"
            v-if="contain.validProp('dataList')&&contain.cacheList.data"
            @click="handlePasteData()"><i class="iconfont icon-paste"></i>
          粘贴数据配置
        </li>
      </ul>
    </li>
    <li class="contentmenu__item">
      <el-icon>
        <el-icon-tools />
      </el-icon>
      操作
      <el-icon class="contentmenu__list--icon">
        <el-icon-caret-right />
      </el-icon>
      <ul class="contentmenu contentmenu__list">
        <li class="contentmenu__item"
            @click="handleSc()">
          <el-icon>
            <el-icon-star />
          </el-icon>
          收藏组件
        </li>
        <li class="contentmenu__item"
            v-if="['html','vue','common'].includes(contain.activeComponent.prop)"
            @click="handleImportBlock()">
          <el-icon>
            <el-icon-upload />
          </el-icon>
          导出组件库
        </li>
        <li class="contentmenu__item"
            @click="handleCopy()"><i class="iconfont icon-copy"></i>
          复制
        </li>
        <li class="contentmenu__item"
            @click="handleShear()"><i class="iconfont icon-shear"></i>
          剪切
        </li>
        <li class="contentmenu__item"
            @click="handleRplica()"><i class="iconfont icon-copy1"></i>
          拷贝
        </li>
        <li class="contentmenu__item"
            v-if="contain.cacheList.copy"
            @click="handlePaste()"><i class="iconfont icon-paste"></i>
          粘贴
        </li>
      </ul>
    </li>
    <li class="contentmenu__item">
      <el-icon>
        <el-icon-position />
      </el-icon>
      位置
      <el-icon class="contentmenu__list--icon">
        <el-icon-caret-right />
      </el-icon>
      <ul class="contentmenu contentmenu__list">
        <li class="contentmenu__item"
            @click="handleTop()">
          <el-icon>
            <el-icon-arrow-up />
          </el-icon>
          置顶
        </li>
        <li class="contentmenu__item"
            @click="handleBottom()">
          <el-icon>
            <el-icon-arrow-down />
          </el-icon>
          置底
        </li>
        <li class="contentmenu__item"
            @click="handleStepTop()">
          <el-icon>
            <el-icon-arrow-up />
          </el-icon>
          上移
        </li>
        <li class="contentmenu__item"
            @click="handleStepBottom()">
          <el-icon>
            <el-icon-arrow-down />
          </el-icon>
          下移
        </li>
        <li class="contentmenu__item"
            @click="handlePostionSelect('left')">
          <svg-icon icon-class="pos1" />
          左对齐
        </li>
        <li class="contentmenu__item"
            @click="handlePostionSelect('center')">
          <svg-icon icon-class="pos5" />
          水平对齐
        </li>
        <li class="contentmenu__item"
            @click="handlePostionSelect('right')">
          <svg-icon icon-class="pos3" />
          右对齐
        </li>
        <li class="contentmenu__item"
            @click="handlePostionSelect('top')">
          <svg-icon icon-class="pos4" />
          顶部对齐
        </li>
        <li class="contentmenu__item"
            @click="handlePostionSelect('middle')">
          <svg-icon icon-class="pos2" />
          垂直对齐
        </li>
        <li class="contentmenu__item"
            @click="handlePostionSelect('bottom')">
          <svg-icon icon-class="pos6" />
          底部对齐
        </li>
      </ul>
    </li>

  </ul>
</template>

<script>
import { dataURLtoFile, createFile, uuid } from '@/utils/utils'
import { uploadImg } from '@/api/visual'
import { addObj } from '@/api/components'
import { getList as getModuleList } from "@/api/category";
export default {
  name: 'contentmenu',
  inject: ["contain"],
  data () {
    return {
      DIC: {},
      selectCount: {
        x1: null,
        x2: null,
        y1: null,
        y2: null
      },
    }
  },
  created () {
    getModuleList({
      categoryModule: 'component',
      current: 1,
      size: 100,
    }).then(res => {
      const data = res.data.data;
      this.DIC.module = [{ label: '全部', value: '' }].concat(data.map(ele => {
        return {
          label: ele.categoryKey,
          value: ele.categoryValue
        }
      }));
    });
  },
  methods: {
    getImg (id) {
      return new Promise(resolve => {
        html2canvas(document.querySelector(id), {
          useCORS: true,
          backgroundColor: null,
          logging: false,
          allowTaint: true
        }).then(canvas => {
          let result = canvas.toDataURL('image/jpeg', 0.1);
          if (result.length < 10) resolve('')
          var file = dataURLtoFile(result, new Date().getTime() + '.jpg');
          var formdata = new FormData();
          formdata.append('file', file)
          uploadImg(formdata).then(res => {
            const data = res.data.data;
            const url = data.fileUrl;
            resolve(url)
          })
        })
      })
    },
    handleImportBlock () {
      let result = {
        vue: {
          type: 0,
          content: this.contain.activeOption.content
        },
        echart: {
          type: 1,
          content: this.contain.activeObj.echartFormatter
        },
        html: {
          type: 2,
          content: this.contain.activeOption.content
        }
      }
      let prop = this.contain.activeComponent.prop
      let block = result[prop] || {}

      this.$DialogForm({
        title: '导出组件',
        width: '400px',
        menuPosition: 'right',
        option: {
          labelWidth: 80,
          submitText: '确认',
          span: 24,
          column: [{
            label: "名称",
            prop: "name",
            rules: [{
              required: true,
              message: "请输入名称",
              trigger: "blur"
            }],
          }, {
            label: "类别",
            prop: "module",
            type: 'select',
            emptyValues: [undefined],
            dicData: this.DIC.module,
            rules: [{
              required: true,
              message: "请选择类别",
              trigger: "blur"
            }],
          }]
        },
        callback: (res) => {
          const form = res.data || {}
          addObj({
            name: form.name,
            module: form.module,
            content: block.content,
            type: block.type
          }).then(() => {
            res.close()
            this.$message.success('导出组件成功')
          })
        }
      })

    },
    handleSc () {
      let obj = this.contain.activeObj;
      this.$DialogForm({
        title: '收藏组件',
        width: '400px',
        menuPosition: 'right',
        option: {
          labelWidth: 80,
          submitText: '确认',
          span: 24,
          column: [{
            label: "名称",
            prop: "name",
            rules: [{
              required: true,
              message: "请输入名称",
              trigger: "blur"
            }],
          }, {
            label: "类别",
            prop: "module",
            type: 'select',
            emptyValues: [undefined],
            dicData: this.DIC.module,
            rules: [{
              required: true,
              message: "请选择类别",
              trigger: "blur"
            }],
          }]
        },
        callback: (res) => {
          const form = res.data || {}
          addObj({
            name: form.name,
            module: form.module,
            content: JSON.stringify([obj], null, 4),
            type: 3
          }).then(() => {
            res.close()
            this.$message.success('组件收藏成功')
          })
        }
      })

    },
    handleOpen (type) {
      if (type == 'data') {
        this.contain.menuTabs = '1'
        this.contain.handleSetting()
      } else if (type == 'transfer') {
        this.contain.menuTabs = '2'
        this.$nextTick(() => {
          this.contain.$refs.transfer.open()
        })
      } else if (type == 'animated') {
        this.contain.menuTabs = '3'
      } else if (type == 'default') {
        this.contain.menuTabs = '4'
      }
    },
    handleRotateX () {
      this.contain.active.forEach(ele => {
        let item = this.contain.findList(ele)
        item.component.rotateX = item.component.rotateX == 180 ? 0 : 180
      })
    },
    handleRotateY () {
      this.contain.active.forEach(ele => {
        let item = this.contain.findList(ele)
        item.component.rotateY = item.component.rotateY == 180 ? 0 : 180
      })
    },
    handlePostionSelect (postion) {
      if (this.contain.isSelectActive) {
        this.contain.activeIndex = null
        this.handleCalcPostionSelect();
      } else {
        this.selectCount = {
          x1: 0,
          x2: this.contain.config.width - 10,
          y1: 0,
          y2: this.contain.config.height - 10
        }
      }
      const x1 = this.selectCount.x1;
      const x2 = this.selectCount.x2;
      const y1 = this.selectCount.y1;
      const y2 = this.selectCount.y2;
      if (postion === 'left') {
        this.handleMoveSelectList(x1, undefined, true, postion);
      } else if (postion === 'center') {
        this.handleMoveSelectList(undefined, y1 + (y2 - y1) / 2, true, postion);
      } else if (postion === 'right') {
        this.handleMoveSelectList(x2, undefined, true, postion);
      } else if (postion === 'top') {
        this.handleMoveSelectList(undefined, y1, true, postion);
      } else if (postion === 'middle') {
        this.handleMoveSelectList(x1 + (x2 - x1) / 2, undefined, true, postion);
      } else if (postion === 'bottom') {
        this.handleMoveSelectList(undefined, y2, true, postion);
      }
    },
    handleMoveSelectList (left, top, type, postion) {
      this.contain.active.forEach(ele => {
        let item = this.contain.findList(ele)
        const component = item.component;
        //水平情况
        if (left !== undefined) {
          let baseLeft = Number(type ? left : (item.left + left).toFixed(2));
          if (postion === 'right') {
            baseLeft = baseLeft - component.width
          }
          else if (postion === 'middle') {
            const obj_center = item.left + component.width / 2;
            baseLeft = item.left + (left - obj_center)
          }

          item.left = baseLeft
        }
        //垂直情况
        if (top !== undefined) {
          let baseTop = Number(type ? top : (item.top + top).toFixed(2));
          if (postion === 'bottom') {
            baseTop = baseTop - component.height
          }
          else if (postion === 'center') {
            const obj_middle = item.top + component.height / 2;
            baseTop = item.top + (top - obj_middle)
          }
          item.top = baseTop
        }
      })
    },
    //计算多选状态下的最大边界值
    handleCalcPostionSelect () {
      this.selectCount = {
        x1: null,
        x2: null,
        y1: null,
        y2: null
      }
      this.contain.active.forEach(ele => {
        ele = this.contain.findList(ele)
        const left = ele.left;
        const top = ele.top;
        const width = ele.component.width;
        const height = ele.component.height;
        if (!this.selectCount.x1) {
          this.selectCount = {
            x1: left,
            x2: left + width,
            y1: top,
            y2: top + height
          }
        }
        if (this.selectCount.x1 > left) this.selectCount.x1 = left;
        if (this.selectCount.x2 < left + width) this.selectCount.x2 = left + width;
        if (this.selectCount.y1 > top) this.selectCount.y1 = top;
        if (this.selectCount.y2 < top + height) this.selectCount.y2 = top + height;
      })
    },
    handleStepBottom () {
      this.handleCommon(false, true);
    },
    handleStepTop () {
      this.handleCommon(true, true);
    },
    //文件夹成组逻辑
    handleCompose () {
      this.$confirm(`是否组合所选择的图层?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        let folder = createFile()
        folder.group = this.contain.group
        let navList;
        this.contain.active.forEach(ele => {
          let { itemList, itemIndex } = this.contain.findnav(ele);
          let obj = itemList.splice(itemIndex, 1)[0];
          folder.children.push(obj);
          navList = itemList;
        });
        navList.unshift(folder);
        this.contain.handleInitActive();
      }).catch(() => { })
    },
    //文件夹解散逻辑
    handleLogout () {
      let ele = this.contain.activeObj
      this.$confirm(`是否解散【${ele.name}】图层?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        let { itemList, itemIndex } = this.contain.findnav(ele.index);
        const list = this.deepClone(ele.children)
        itemList.splice(itemIndex, 1);
        list.forEach(item => itemList.push(item));
        this.contain.handleInitActive();
      }).catch(() => { })
    },
    //删除
    handleDel (tip = true) {
      const callback = () => {
        this.contain.active.forEach(ele => {
          const { itemList, itemIndex } = this.contain.findnav(ele);
          itemList.splice(itemIndex, 1);
        });
        this.contain.handleInitActive();
      }
      if (tip) {
        this.$confirm(`是否删除所选图层?`, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          callback()
        }).catch(() => { })
      } else {
        callback()
      }

    },
    handleCopyData () {
      this.contain.cacheList.data = this.contain.activeObj.dataList
      this.$message.success('复制数据配置成功')
    },
    handlePasteData () {
      if (!this.contain.cacheList.data) return
      this.contain.activeObj.dataList = this.contain.cacheList.data
      this.$message.success('粘贴数据配置成功')
    },
    //粘贴
    handlePaste (params = {}) {
      const { tip = '粘贴组件成功' } = params
      this.beforeOpen && this.beforeOpen()
      if (!this.contain.cacheList.copy) return
      let active = []
      let { itemList = this.contain.nav } = this.contain.findnav(this.contain.activeIndex)
      const setItemParams = (list, { group }) => {
        list.forEach(item => {
          item.group = group
          if (item.children) setItemParams(item.children, { group })
        })
      }
      this.contain.cacheList.copy.forEach(ele => {
        setItemParams([ele], { group: this.contain.group })
        itemList.unshift(ele)
        active.push(ele.index)
      })
      this.contain.cacheList.copy = null;
      this.$nextTick(() => this.contain.selectNav(active))
      tip && this.$message.success(tip)
    },
    //剪切
    handleShear () {
      this.handleRplica({
        tip: '剪切组件成功',
        add: false,
        fn: () => this.handleDel(false)
      });
    },
    //拷贝
    handleRplica (params = {}) {
      const { tip = "拷贝组件成功", fn, add = true } = params
      this.handleCopy({
        add,
        fn: (list) => {
          this.contain.cacheList.copy = list
          tip && this.$message.success(tip)
          fn && fn()
        }
      })
    },
    //复制`
    handleCopy (params = {}) {
      const { fn, add = true } = params
      let active = []
      let fnList = []
      const setItemParams = (list = [], isActice = true) => {
        list.forEach(ele => {
          const index = uuid()
          ele.index = index;
          if (isActice) active.push(index)
          if (ele.children) {
            ele.menu = false
            setItemParams(ele.children, false)
          }
        })
      }
      this.contain.active.forEach(ele => {
        const { item, itemList } = this.contain.findnav(ele);
        let obj = this.deepClone(item);
        if (add) setItemParams([obj])
        if (fn) {
          fnList.push(obj)
        } else {
          itemList.unshift(obj)
        }
      });
      if (fn) {
        fn(fnList)
      } else {
        this.$nextTick(() => this.contain.selectNav(active))
        this.$message.success('复制组件成功')
      }
    },
    // 图层的上下移动方法 
    handleCommon (top = false, step = false) {
      this.contain.active.forEach(ele => {
        let { itemList, itemIndex } = this.contain.findnav(ele);
        let obj = itemList.splice(itemIndex, 1)[0];
        if (step) {
          itemList.splice(top ? (itemIndex - 1) : (itemIndex + 1), 0, obj)
        } else {
          itemList[top ? 'unshift' : 'push'](obj)
        }
      })
    },
    handleTop () {
      this.handleCommon(true);
    },
    handleBottom () {
      this.handleCommon();
    }
  }
}
</script>

<style lang="scss">
.contentmenu {
  width: 180px;
  display: none;
  z-index: 99999;
  list-style: none;
  box-shadow: var(--shadow-light);
  padding: 0;
  background: var(--bg-color-secondary);
  color: var(--text-color-light);
  border-radius: 5px;
}
.contentmenu__list {
  display: block;
  position: absolute;
  top: 0;
  left: 180px;
  &--icon {
    position: absolute;
    right: 2px;
  }
}
.contentmenu__item {
  display: flex;
  align-items: center;
  position: relative;
  z-index: 10000;
  list-style: none;
  padding: 6px 12px;
  cursor: pointer;
  position: relative;
  font-size: 14px;
}
.contentmenu__item:hover {
  background-color: var(--bg-color-hover);
}
.contentmenu__item {
  i,
  svg {
    margin-right: 5px;
  }
}
.contentmenu__item :first-child {
  padding-top: 5px;
}
</style>
