<template>
  <div style="padding: 0 10px 20px 10px">
    <el-row :gutter="4">
      <el-col :span="4">
        <el-card style="height: 100%;" :style="{'opacity':isDrag ? '0.4' : '1' }">
          <template v-slot:title>
            <p>组件</p>
          </template>
          <div
            v-for="(item, index) in layout"
            :key="index"
            class="cpn-name__item"
            :class="{ 'cpn-name__item--disable': statusFormat(item.i) }"
            :draggable="!statusFormat(item.i)"
            @dragstart="isDrag = true"
            @dragend="dragEnd(item, $event)"
          >
            <i class="el-icon-folder-remove" />
            <span>{{ item.name }}</span>
            <el-button
              v-show="statusFormat(item.i)"
              type="danger"
              size="mini"
              ghost
              @click="removeLayout(item.i)"
            >移除</el-button>
          </div>
        </el-card>
      </el-col>

      <el-col :span="20">
        <el-card :class="{'drag-body':isDrag}">
          <template #header>
            <div style="display: flex;align-items: center;">
              <p>布局</p>
              <div style="margin-left: auto;">
                <el-button size="small" type="primary" style="margin-right: 10px;" @click="sync">同步</el-button>
                <el-button size="small" type="primary" @click="save">保存</el-button>
              </div>
            </div>
          </template>

          <grid-layout
            id="grid-card"
            class="gird-card"
            :layout.sync="layoutList"
            :col-num="12"
            :row-height="40"
            :is-draggable="true"
            :is-resizable="true"
            :is-mirrored="false"
            :vertical-compact="true"
            :margin="[10, 10]"
            :auto-size="true"
            :use-css-transforms="true"
          >
            <grid-item
              v-for="item in layoutList"
              :key="item.i"
              :x="item.x"
              :y="item.y"
              :w="item.w"
              :h="item.h"
              :i="item.i"
              style="touch-action: none"
            >
              <component
                :is="item.component"
                style="position: absolute; inset: 0 0 0 0;"
              />
            </grid-item>
          </grid-layout>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import VueGridLayout from 'vue-grid-layout'
const files = require.context(
  '@/views/system/DashboardComponents',
  false,
  /.vue$/
)
const cpns = files.keys().map((key) => {
  return files(key).default || files(key)
})
const layout = cpns.map((item) => {
  return {
    ...item.layout,
    component: item
  }
})
export default {
  components: {
    'GridLayout': VueGridLayout.GridLayout,
    'GridItem': VueGridLayout.GridItem
  },
  data() {
    return {
      layout,
      layoutList: [],
      isDrag: false,

      grid: {
        x: 0,
        y: 0
      }
    }
  },
  computed: {
    statusFormat() {
      return function(i) {
        const iArr = this.layoutList.map((item) => item.i)
        return iArr.indexOf(i) !== -1
      }
    }
  },
  mounted() {
    this.grid = document.getElementById('grid-card').getBoundingClientRect()
  },
  created() {
    this.$store.dispatch('app/getLayout').then(res => {
      this.layoutList = res.map(item => {
        layout.forEach(lay => {
          lay.i === item.i ? item.component = lay.component : ''
        })
        return item
      })
    })
  },
  methods: {
    dragEnd(item, e) {
      this.isDrag = false
      if (e.clientX >= this.grid.x && e.clientY >= this.grid.y) {
        this.layoutList.push(item)
      }
    },

    removeLayout(i) {
      let temp = -1
      this.layoutList.forEach((item, index) => {
        if (i === item.i) {
          temp = index
        }
      })
      this.layoutList.splice(temp, 1)
    },

    async sync() {
      await this.$store.dispatch('app/setLayout')

      this.$store.dispatch('app/getLayout').then(res => {
        this.layoutList = res.map(item => {
          layout.forEach(lay => {
            lay.i === item.i ? item.component = lay.component : ''
          })
          return item
        })
      })
    },
    save() {
      const layout = this.layoutList.map(item => {
        return {
          x: item.x,
          y: item.y,
          w: item.w,
          h: item.h,
          i: item.i
        }
      })
      this.$store.dispatch('app/saveLayout', layout)
    }
  }
}
</script>

<style scoped lang="scss">
.gird-card {
  min-height: 200px;
}
.cpn-name__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: rgb(100, 100, 100);
  border-radius: 4px;
  background-color: rgba(94, 181, 218, 0.3);
  cursor: move;

  padding: 6px 6px;
  & > i {
    padding-right: 6px;
  }
  & > span {
    flex: 1;
  }
  & + div {
    margin-top: 10px;
  }

  &--disable {
    cursor: no-drop;
    background-color: rgba(218, 94, 98, 0.3);
  }
}
.drag-body{
  transition: all .4s;
  background: rgba(32, 160, 255, 0.3);
  opacity: .7;
}

.fade-in {
  animation: fade-in 800ms cubic-bezier(0.39, 0.575, 0.565, 1) both;
}
@keyframes fade-in {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
.fade-out {
  animation: fade-out 600ms ease-out both;
}
@keyframes fade-out {
  0% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

::v-deep .el-card__header {
  padding: 10px 20px;
}
</style>
