<template>
  <div class="panel">
    <ul>
      <li>
        <label>组件</label>
        <div>
          <el-scrollbar class="scrollbar-fullheight">
            <div class="control-list">
              <div class="widget-cate">图表组件</div>
              <div class="field-div">
                <draggable
                  class="flex-container"
                  tag="div"
                  :list="datavToolMap.chart.items"
                  v-bind="{
                    group: {name: 'datav', pull: 'clone', put: false},
                    sort: false,
                    ghostClass: 'ghost'
                  }"
                  @end="handleMoveEnd"
                  @start="handleMoveStart"
                  :move="handleMove"
                >
                  <div
                    class="chart-item"
                    v-for="(item, key, index) in datavToolMap.chart.items"
                    :key="index"
                  >
                    <div class="chart-item-img">
                      <img
                        :src="item.icon"
                        :title="item.name"
                        class="image drag-middle"
                      />
                    </div>
                    <div class="chart-item-name">{{ item.name }}</div>
                  </div>
                </draggable>
              </div>

              <div class="widget-cate">datav组件</div>
              <div class="field-div">
                <draggable
                  class="flex-container"
                  tag="div"
                  :list="datavToolMap.elements.items"
                  v-bind="{
                    group: {name: 'datav', pull: 'clone', put: false},
                    sort: false,
                    ghostClass: 'ghost'
                  }"
                  @end="handleMoveEnd"
                  @start="handleMoveStart"
                  :move="handleMove"
                >
                  <div
                    class="chart-item"
                    v-for="(item, key, index) in datavToolMap.elements.items"
                    :key="index"
                  >
                    <div class="chart-item-img">
                      <img
                        :src="item.icon"
                        :title="item.name"
                        class="image drag-middle"
                      />
                    </div>
                    <div>{{ item.name }}</div>
                  </div>
                </draggable>
              </div>

              <div class="widget-cate">基础组件</div>
              <div class="field-div">
                <draggable
                  class="flex-container"
                  tag="div"
                  :list="decorationMap.baseEl.items"
                  v-bind="{
                    group: {name: 'datav', pull: 'clone', put: false},
                    sort: false,
                    ghostClass: 'ghost'
                  }"
                  @end="handleMoveEnd"
                  @start="handleMoveStart"
                  :move="handleMove"
                >
                  <div
                    class="chart-item"
                    v-for="(item, key, index) in decorationMap.baseEl.items"
                    :key="index"
                  >
                    <div class="chart-item-img">
                      <img
                        :src="item.icon"
                        :title="item.name"
                        class="image drag-small"
                      />
                    </div>
                    <div>{{ item.name }}</div>
                  </div>
                </draggable>
              </div>

              <div class="widget-cate">装饰组件</div>
              <div class="field-div">
                <draggable
                  class="flex-container"
                  tag="div"
                  :list="decorationMap.styleEl.items"
                  v-bind="{
                    group: {name: 'datav', pull: 'clone', put: false},
                    sort: false,
                    ghostClass: 'ghost'
                  }"
                  @end="handleMoveEnd"
                  @start="handleMoveStart"
                  :move="handleMove"
                >
                  <div
                    class="chart-item"
                    v-for="(item, key, index) in decorationMap.styleEl.items"
                    :key="index"
                  >
                    <div class="chart-item-img">
                      <img
                        :src="item.icon"
                        :title="item.name"
                        class="image drag-small"
                      />
                    </div>
                    <div>{{ item.name }}</div>
                  </div>
                </draggable>
              </div>

              <div class="widget-cate">边框组件</div>
              <div class="field-div" style="border-bottom: none">
                <draggable
                  class="flex-container"
                  tag="div"
                  :list="decorationMap.borderEl.items"
                  v-bind="{
                    group: {name: 'datav', pull: 'clone', put: false},
                    sort: false,
                    ghostClass: 'ghost'
                  }"
                  @end="handleMoveEnd"
                  @start="handleMoveStart"
                  :move="handleMove"
                >
                  <div
                    class="chart-item"
                    v-for="(item, key, index) in decorationMap.borderEl.items"
                    :key="index"
                  >
                    <div class="chart-item-img">
                      <img
                        :src="item.icon"
                        :title="item.name"
                        class="image drag-small"
                      />
                    </div>
                    <div>{{ item.name }}</div>
                  </div>
                </draggable>
              </div>
            </div>
          </el-scrollbar>
        </div>
      </li>
      <li>
        <label>图层</label>
        <div>
          <el-scrollbar class="scrollbar-fullheight">
            <div class="" v-on:click="onceClick($event)">
              <div
                class="layer-item"
                :class="{
                  active:
                    (selectWidget && item.key == selectWidget.key) ||
                    selectWidgetMap[item.key]
                }"
                v-for="(item, index) in sortList"
                @click="selectItem(item)"
                @contextmenu.prevent="openMenu(item, index)"
                v-dragging="{
                  item: item,
                  key: item.key,
                  list: sortList,
                  group: 'layerSort'
                }"
                :key="item.key"
              >
                <div class="layer-icon">
                  <img
                    :src="item.icon"
                    :title="item.name"
                    class="image layer-img"
                    style="
                      position: relative;
                      display: inline-block;
                      overflow: hidden;
                    "
                  />
                </div>
                <span>{{ item.name }}</span>
              </div>
            </div>
            <div
              v-show="menuVisible && selectWidget"
              class="container"
              :style="{zoom: 1, left: left + 'px', top: top + 'px'}"
            >
              <div class="m-ctxMenu">
                <ul>
                  <li class="z-clickable" @click="handleWidgetClone">复制</li>
                  <li class="z-clickable" @click="handleWidgetDelete">删除</li>
                  <li class="z-clickable" @click="handleWidgetRank('top')">
                    置于顶层
                  </li>
                  <li class="z-clickable" @click="handleWidgetRank('bottom')">
                    置于底层
                  </li>
                  <li class="z-clickable" @click="handleWidgetRank('pre')">
                    上移一层
                  </li>
                  <li class="z-clickable" @click="handleWidgetRank('next')">
                    下移一层
                  </li>
                </ul>
              </div>
            </div>
          </el-scrollbar>
        </div>
      </li>
      <li @mouseenter="handleClick">
        <label>组件库</label>
        <div>
          <el-scrollbar class="scrollbar-fullheight">
            <div>
              <draggable
                class="flex-container"
                tag="div"
                :list="templateList"
                v-bind="{
                  group: {name: 'datav', pull: 'clone', put: false},
                  sort: false,
                  ghostClass: 'ghost'
                }"
                @end="handleMoveEnd"
                @start="handleMoveStartTemplate"
                :move="handleMove"
              >
                <div
                  class="template-item"
                  v-for="(item, key, index) in templateList"
                  :key="index"
                >
                  <datav-cover
                    :fileId="item.screenCaptureId"
                    :key="item.screenCaptureId ? item.screenCaptureId : item.id"
                    class="template-item_img"
                  />
                  <div class="col-title">{{ item.name }}</div>
                </div>
              </draggable>
            </div>
          </el-scrollbar>
        </div>
      </li>
    </ul>
  </div>
</template>
<script>
import Draggable from 'vuedraggable'
import deepmerge from 'deepmerge'
import portal from '../../api/portal'
import WidgetFormBus from '@/components/form/bus/WidgetFormBus.js'
import {datavToolMap, datavDecorationData} from '@/api/datavConfig.js'
const DatavCover = () => import('@/components/portal/datav/DatavCover.vue')
import req from '@/request.js'

export default {
  name: 'datav-field-panel',
  components: {Draggable, DatavCover, WidgetFormBus},
  props: {
    data: {
      type: Object,
      default() {
        return {}
      }
    },
    select: {
      type: Object,
      default() {
        return {alias: ''}
      }
    },
    selectMap: {
      type: Object,
      default() {
        return {}
      }
    },
    layoutObj: {
      type: Object
    }
  },
  data() {
    return {
      widgetForm: this.data,
      selectWidget: this.select,
      activeName: 'fieldList',
      top: 0,
      left: 0,
      selectIndex: 0,
      isDragging: false,
      datavToolMap: JSON.parse(JSON.stringify(datavToolMap)),
      decorationMap: JSON.parse(JSON.stringify(datavDecorationData)),
      columnToolMap: {}, //图表、datav组件
      decorationToolMap: {}, //装饰组件
      menuVisible: false,
      templateList: [],
      selectWidgetMap: this.selectMap
    }
  },
  created() {
    this.initFieldMap()
  },
  watch: {
    data: {
      handler(val) {
        this.widgetForm = val
      },
      deep: true
    },
    widgetForm: {
      handler(val) {
        if (!this.isDragging) {
          this.$emit('update:data', val)
        }
      },
      deep: true
    },
    select: {
      handler(val) {
        this.selectWidget = val
      },
      deep: true
    },
    selectWidget: {
      handler(val) {
        this.menuVisible = false
        this.$emit('update:select', val)
      },
      deep: true
    },
    selectMap: {
      handler(val) {
        this.selectWidgetMap = val
      },
      deep: true
    },
    selectWidgetMap: {
      handler(val) {
        this.$emit('update:selectMap', val)
      },
      deep: true
    }
  },
  computed: {
    sortList() {
      return this.widgetForm.list.sort((a, b) => b.zIndex - a.zIndex)
    }
  },
  methods: {
    handleMoveEnd: function() {},
    handleMoveStart: function(evt) {
      WidgetFormBus.$emit('datavHandleMoveStart')
      evt.item._underlying_vm_ = deepmerge({}, evt.item._underlying_vm_, {
        clone: true
      })
    },
    handleMoveStartTemplate: function(evt) {
      evt.item._underlying_vm_ = deepmerge({}, evt.item._underlying_vm_, {
        clone: true
      })
    },
    handleMove: function() {},
    initFieldMap() {
      let _this = this
      for (const key in this.datavToolMap) {
        if (Object.hasOwnProperty.call(this.datavToolMap, key)) {
          const obj = this.datavToolMap[key]
          if (obj.items && obj.items.length > 0) {
            _this.columnToolMap[key] = {desc: obj.desc, items: []}
            obj.items.forEach(item => {
              _this.columnToolMap[key].items.push({
                type: item.type,
                name: item.name,
                alias: item.alias,
                icon: item.icon,
                template: item.template,
                zIndex: item.zIndex
              })
            })
          }
        }
      }
      for (const key in this.decorationMap) {
        if (Object.hasOwnProperty.call(this.decorationMap, key)) {
          const obj = this.decorationMap[key]
          if (obj.items && obj.items.length > 0) {
            _this.decorationToolMap[key] = {desc: obj.desc, items: []}
            obj.items.forEach(item => {
              _this.decorationToolMap[key].items.push({
                name: item.name,
                alias: item.alias,
                icon: item.icon,
                zIndex: item.zIndex
              })
            })
          }
        }
      }
    },
    handleClick() {
      this.getAllTemplate()
    },
    selectItem(item) {
      if (!window.event.ctrlKey) {
        this.selectWidget = item
        this.menuVisible = false
        this.selectWidgetMap = {}
      }
    },
    handleWidgetClone() {
      let index = this.selectIndex
      if (this.selectWidget) {
        let cloneData = {
          ...this.selectWidget,
          options: {...this.selectWidget.options},
          key: Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 99999)
        }
        this.data.list.splice(index, 0, cloneData)

        this.$nextTick(() => {
          let newIndex = index + 1
          this.selectWidget = this.data.list[newIndex]
          this.selectIndex = newIndex
        })
        this.closeMenu()
      }
    },
    openMenu(el, index) {
      if (el && this.selectWidget && this.selectWidget.key === el.key) {
        this.left = window.event.clientX - 10
        this.top = window.event.clientY - 95 // fix 位置bug
        this.menuVisible = true
        this.selectIndex = index
      }
    },
    closeMenu() {
      this.menuVisible = false
    },
    onceClick(evt) {
      if (!this.selectWidget) {
        this.closeMenu()
      } else {
        if (
          !(
            evt.x >= this.selectWidget.x &&
            evt.x <= this.selectWidget.x + this.selectWidget.width &&
            evt.y >= this.selectWidget.y &&
            evt.y <= this.selectWidget.y + this.selectWidget.height
          )
        ) {
          this.closeMenu()
        }
      }
    },
    handleWidgetDelete() {
      const index = this.selectIndex
      if (this.data.list.length - 1 === index) {
        if (index === 0) {
          this.selectWidget = {}
        } else {
          this.selectWidget = this.data.list[index - 1]
        }
      } else {
        this.selectWidget = this.data.list[index + 1]
      }

      this.$nextTick(() => {
        this.data.list.splice(index, 1)
      })
      this.closeMenu()
    },
    handleWidgetRank(type) {
      if (this.selectWidget) {
        switch (type) {
          case 'top':
            const maxIndex = this.getCurrentMaxZindex()
            this.selectWidget.zIndex = maxIndex + 1
            break
          case 'bottom':
            const minIndex = this.getCurrentMinZindex()
            this.selectWidget.zIndex = minIndex - 1
            break
          case 'pre':
            ++this.selectWidget.zIndex
            break
          case 'next':
            --this.selectWidget.zIndex
            break
        }
      }
      this.closeMenu()
    },
    getCurrentMaxZindex() {
      //获取当前元素中最大的z-index值
      let array = this.getCurrentZindexSort()
      if (array && array.length > 0) {
        return array[array.length - 1].zIndex
      }
      return 0
    },
    getCurrentMinZindex() {
      //获取当前元素中最大的z-index值
      let array = this.getCurrentZindexSort()
      if (array && array.length > 0) {
        return array[0].zIndex
      }
      return 0
    },
    getCurrentZindexSort() {
      //所有元素按z-index排序
      try {
        let arr = JSON.parse(JSON.stringify(this.data.list))
        arr.sort((obj1, obj2) => {
          return obj1.zIndex - obj2.zIndex
        })
        return arr
      } catch (error) {
        return null
      }
    },
    getAllTemplate() {
      let _this = this
      let query = []
      query.push({
        property: 'type_',
        value: 'unit',
        group: 'type',
        operation: 'EQUAL',
        relation: 'AND'
      })
      query.push({
        property: 'enable',
        value: 1,
        group: 'type',
        operation: 'EQUAL',
        relation: 'AND'
      })
      let param = {
        pageBean: {page: 1, pageSize: -1, total: false},
        querys: query,
        sorter: [{direction: 'DESC', property: 'CREATE_TIME_'}]
      }
      portal
        .getLayoutManagerPage(param)
        .then(data => {
          if (data && data.rows) {
            _this.templateList = data.rows
          }
        })
        .finally(() => {})
    }
  },
  mounted() {
    document.body.ondrop = function(event) {
      let isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1
      if (isFirefox) {
        event.preventDefault()
        event.stopPropagation()
      }
    }
    this.$dragging.$on('dragged', obj => {
      this.isDragging = true
      let _this = this
      if (
        obj.hasOwnProperty('draged') &&
        obj.hasOwnProperty('to') &&
        obj.hasOwnProperty('value')
      ) {
        const list = obj.value.list
        const draged = obj.draged
        const to = obj.to
        const nIndex = list.findIndex(it => it.key === draged.key)
        const toIndex = list.findIndex(it => it.key === to.key)
        let zIndex = draged.zIndex
        if (nIndex > toIndex) {
          //往下拉
          zIndex = to.zIndex - 1
        } else {
          //往上拉
          zIndex = to.zIndex + 1
        }
        _this.$set(_this.selectWidget, 'zIndex', zIndex)
      }
    })
    this.$dragging.$on('dragend', () => {
      this.isDragging = false
      this.$emit('update:data', this.widgetForm)
    })
  }
}
</script>
<style lang="scss" scoped>
@import '@/assets/css/form-editor.scss';

.panel {
  height: 100%;
  background: #282b30;
  position: relative;
  /deep/ .el-tabs__content {
    height: calc(100% - 60px);
  }
  /deep/ .el-tab-pane {
    height: 100%;
  }
  /deep/ .el-tabs__nav {
    margin-left: 10px;
  }
  /deep/ .el-tabs__item {
    font-size: 13px;
  }
  /deep/ .el-collapse-item__header {
    text-indent: 10px;
  }
  .panel__tabs {
    height: 100%;
  }
  .scrollbar-fullheight {
    height: 100%;
  }
  .panel__copy--btndiv {
    text-align: center;
  }

  > ul {
    margin: 0;
    padding: 0;
    > li {
      height: 40px;
      text-align: center;
      > label {
        color: #81888f;
        font-size: 12px;
        line-height: 40px;
      }
      > div {
        display: none;
        position: absolute;
        background: #1b1d20;
        width: 350px;
        height: 100%;
        top: 0;
        left: 50px;
        z-index: 10;
      }
      &:hover {
        background: #1b1d20;
        > label {
          color: #409eff;
        }
        > div {
          display: block;
        }
      }
    }
  }
}

.widget-cate {
  font-weight: bold;
  color: #6c7279;
  font-size: 13px;
  text-align: left;
  margin-bottom: 15px;
}

ul.flex-container {
  margin: 0;
  list-style: none;
  padding: 10px 5px;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}

ul.flex-container > li.flex-item {
  padding: 5px;
  height: 17px;
  border: 1px solid #ccc;
  margin: 4px;
  width: 87px;
  border-radius: 5px;
  cursor: pointer;
}

ul.flex-container > li.flex-item:hover {
  box-shadow: 0 2px 5px rgba(86, 96, 117, 0.15);
}

li.flex-item > a > i {
  font-size: 16px;
}

li.flex-item > a > span {
  margin-left: 8px;
}
.control-list {
  padding: 15px;
}
.field-div {
  border-bottom: 1px solid #3a3f4a;
  margin-bottom: 15px;

  .flex-container {
    display: flex;
    flex-wrap: wrap;
  }
  .chart-item {
    width: 100px;
    text-align: center;
    margin-bottom: 15px;
    margin-right: 10px;
    color: #cbd3db;
    .chart-item-img {
      height: 62px;
      background: #1a2c44;
      display: flex;
      align-items: center;
      justify-content: center;
      margin-bottom: 5px;
    }
  }
  .chart-item:nth-child(3n) {
    margin-right: 0;
  }
}

.layer-item {
  box-sizing: border-box;
  display: flex;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  height: 40px;
  position: relative;
  cursor: pointer;
  -webkit-box-flex: 0;
  -ms-flex: none;
  flex: none;
  font-size: 12px;
  border-bottom: 1px solid #282b30;
  padding: 0 20px;
  color: #6c7279;
}

.layer-item.active {
  // outline: 1px solid $--color-primary;
  background: #121416;
  color: #409eff;
}
.layer-icon {
  color: #409eff;
  margin-right: 10px;
  width: 50px;
  height: 30px;
  line-height: 30px;
  text-align: center;
  display: block;
  // border: 1px solid #3a46590d;
  background: #1a2c44;
}
.layer-img {
  width: 28px;
  height: 28px;
  display: table-cell;
  vertical-align: middle;
  text-align: center;
}
.container {
  width: 150px;
  position: absolute;
  z-index: 2004;
}
.m-ctxMenu {
  background: #fff;
  border: 1px solid #ccc;
  box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.16);
  border-radius: 2px;
}
.m-ctxMenu li {
  cursor: pointer;
  position: relative;
  font-size: 12px;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  -ms-box-sizing: border-box;
  -o-box-sizing: border-box;
  box-sizing: border-box;
  padding-left: 24px;
  padding-right: 18px;
  height: 32px;
  line-height: 32px;
  min-width: 130px;
  background-color: #fff;
  white-space: nowrap;
}
.m-ctxMenu li:before {
  position: absolute;
  left: 8px;
  line-height: 32px;
}
.m-ctxMenu li:hover {
  background: #ccc;
}
.m-ctxMenu .z-disabled {
  color: #ccc;
}
.m-ctxMenu .shortcut {
  float: right;
  color: #8f8f8f;
}
.m-ctxMenu li .u-icn-angle-right {
  left: auto;
  right: 8px;
}
.m-ctxMenu li .u-icn {
  position: absolute;
  left: 8px;
  top: 10px;
  font-size: 12px;
}
.u-icn {
  display: inline-block;
  font-family: 'youdata';
  font-style: normal;
  font-weight: normal;
  font-variant: normal;
  line-height: 1;
  text-decoration: inherit;
  text-rendering: optimizeLegibility;
  text-transform: none;
  -moz-osx-font-smoothing: grayscale;
  -webkit-font-smoothing: antialiased;
  vertical-align: middle;
  margin-bottom: 2px;
}
.m-ctxMenu li > ul.right {
  left: 100%;
}
.m-ctxMenu li > ul {
  position: absolute;
  border: 1px solid #ccc;
}
ol,
ul {
  list-style: none;
  padding-left: 0px;
}
.m-ctxMenu li > ul.bottom {
  top: 0;
}
.content-box {
  display: grid;
  grid-template-columns: 2fr 3fr 5fr 3fr 2fr;
}
.drag-small {
  height: 75%;
  position: relative;
  display: inline-block;
  overflow: hidden;
}
.drag-middle {
  height: 75%;
  position: relative;
  display: inline-block;
  overflow: hidden;
}
.template-item {
  display: flex;
  align-items: center;
  box-sizing: border-box;
  width: 100%;
  height: 40px;
  line-height: 40px;
  border-bottom: 1px solid #282b30;
  padding: 0 20px;
  cursor: pointer;
  font-size: 12px;

  .template-item_img {
    width: 50px;
    height: 30px;
    background: #1a2c44;
    margin-right: 10px;
  }
}
.template-icon {
  width: 38px;
  height: 38px;
  text-align: center;
  margin-left: 15px;
  margin-right: 15px;
}
.col-title {
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding-left: 5px;
  color: #6c7279;
  line-height: 40px;
}
</style>
