<template>

  <el-button
    :type="type"
    @click="visible = true"
  >
    <template slot="default">
      <div class="custom-column-button">
        <i class="el-icon-column"></i>
        <span>自定义列</span>
      </div>
    </template>
    <el-dialog
      custom-class="bi-column-dialog"
      title="自定义列"
      :visible.sync="visible"
      :width="dialogWidth"
      top="0vh"
      append-to-body
      @open="handleOpen"
      @close="close"
    >
      <div
        class="dialog-body"
        style="min-height: 160px"
      >
        <div class="bi-column-container">
          <div class="checkbox-container">
            <el-card
              class="box-card"
              shadow="never"
            >
              <div
                slot="header"
                class="clearfix"
              >
                <div class="box-card-header">
                  <span>可操作性的列</span>
                  <span style="display: inline-block">
                    <el-checkbox
                      v-model="checkAllData"
                      label="全选"
                      @change="checkAll"
                    >
                      全选
                    </el-checkbox>
                  </span>
                </div>
              </div>
              <div
                v-for="(item, index) in colList"
                :key="index"
                class="checkbox-group"
              >
                <p
                  v-show="colList.length>1"
                  class="checkbox-title"
                >
                  <el-checkbox
                    v-model="item.status"
                    @change="
                      (val) => {
                        return handleCheckGroupAllChange(val, item);
                      }
                    "
                  >{{ item.content }}</el-checkbox>
                </p>
                <p>
                  <el-checkbox-group
                    v-model="checkList"
                    :true-label="1"
                    :false-label="0"
                    @change="handleCheckGroupAll(item)"
                  >
                    <el-checkbox
                      v-for="(city, cityIndex) in item.children"
                      :key="cityIndex"
                      :label="city.name"
                      style="width:120px;margin:0 15px 15px 0;"
                    >
                      {{ city.content }}
                    </el-checkbox>
                  </el-checkbox-group>
                </p>
              </div>
            </el-card>

          </div>
          <div class="column-container">
            <el-card
              class="box-card"
              shadow="never"
            >
              <div
                slot="header"
                class="column-title"
              >
                <span>已选{{ columnLength }}列</span>
                <el-button
                  type="text"
                  @click="clearAll"
                >清空全部</el-button>
              </div>
              <transition-group
                type="transition"
                :name="!drag ? 'flip-list' : null"
              >
                <div key="left">
                  <p class="column-group-title">左侧固定列</p>
                  <div class="column-configurable">
                    <draggable
                      v-model="leftColumnList"
                      group="column"
                      v-bind="dragOptions"
                      @start="drag = true"
                      @end="drag = false"
                    >
                      <!-- <transition-group
                    type="transition"
                    :name="!drag ? 'flip-list' : null"
                  > -->
                      <div
                        v-for="column in leftColumnList"
                        :key="column.prop"
                        class="selected-column-item"
                      >
                        <i class="el-icon-drags"></i>
                        <div class="column-name">{{ column.content||column.label }}</div>
                        <i
                          class="el-icon-close column-close"
                          @click="closeColumn(column.prop)"
                        ></i>
                      </div>
                      <!-- </transition-group> -->
                    </draggable>
                  </div>
                </div>

                <div key="center">
                  <p class="column-group-title">中间不固定列</p>
                  <div class="column-configurable">
                    <draggable
                      v-model="columnList"
                      group="column"
                      v-bind="dragOptions"
                      @start="drag = true"
                      @end="drag = false"
                    >
                      <!-- <transition-group
                    type="transition"
                    :name="!drag ? 'flip-list' : null"
                  > -->
                      <div
                        v-for="column in columnList"
                        :key="column.prop"
                        class="selected-column-item"
                      >
                        <i class="el-icon-drags"></i>
                        <div class="column-name">{{ column.content||column.label }}</div>
                        <i
                          class="el-icon-close column-close"
                          @click="closeColumn(column.prop)"
                        ></i>
                      </div>
                      <!-- </transition-group> -->
                    </draggable>
                  </div>
                </div>

                <div key="right">
                  <p class="column-group-title">右侧固定列</p>
                  <div class="column-configurable">
                    <draggable
                      v-model="rightColumnList"
                      group="column"
                      v-bind="dragOptions"
                      @start="drag = true"
                      @end="drag = false"
                    >
                      <!-- <transition-group
                    type="transition"
                    :name="!drag ? 'flip-list' : null"
                  > -->
                      <div
                        v-for="column in rightColumnList"
                        :key="column.prop"
                        class="selected-column-item"
                      >
                        <i class="el-icon-drags"></i>
                        <div class="column-name">{{ column.content||column.label }}</div>
                        <i
                          class="el-icon-close column-close"
                          @click="closeColumn(column.prop)"
                        ></i>
                      </div>
                      <!-- </transition-group> -->
                    </draggable>

                  </div>
                </div>
              </transition-group>

            </el-card>
          </div>
        </div>
      </div>
      <span
        slot="footer"
        class="dialog-footer"
        style="display: flex; justify-content: space-between;padding:4px"
      >
        <span style="display: inline-block; line-height: 32px">
          <!-- <el-checkbox
            v-model="checkAllData"
            label="全选"
            @change="checkAll"
          >
            全选
          </el-checkbox> -->
        </span>
        <div>
          <el-button @click="close">取消</el-button>
          <el-button
            type="primary"
            @click="ok"
          >确定</el-button>
        </div>
      </span>
    </el-dialog>
  </el-button>
</template>

<script>
import draggable from 'vuedraggable'
export default {
  name: 'BiCustomColumn',
  components: {
    draggable
  },
  props: {
    columnName: {
      type: String,
      require: true,
      default: ''
    },
    dialogWidth: {
      type: String,
      default: '770px'
    },
    viewModel: {
      type: String,
      default: ''
    },
    type: {
      type: String,
      default: ''
    },
    listType: {
      type: String,
      require: true,
      default: ''
    },
    checkData: {
      type: Array,
      require: true,
      default: () => {
        return []
      }
    },
    tableColumn: {
      type: Array,
      default: () => {
        return []
      }
    },
    defaultList: {
      type: Array,
      default: () => {
        return []
      }
    },
    defaultColumn: {
      type: Object,
      default: () => {
        return {
          left: [],
          center: [],
          right: []
        }
      }
    }
  },

  data() {
    return {
      tableColumnList: this.tableColumn,
      visible: false,
      colList: [],

      checkList: [], // 存放勾选数据
      checkAllData: false,

      drag: false,
      draggableList: [],
      leftColumnList: [],
      columnList: [],
      rightColumnList: []
    }
  },
  computed: {
    columnLength() {
      return this.leftColumnList.length + this.columnList.length + this.rightColumnList.length
    },
    dragOptions() {
      return {
        animation: 200,
        group: 'description',
        disabled: false,
        ghostClass: 'ghost',
        class: 'list-group'
      }
    }
  },
  watch: {
    colList: {
      handler(now) {
        let i = true
        now.forEach((item) => {
          item.status = Boolean(item.status)
          if (item.status) {
            this.checkAllData = item.status
          } else {
            i = false
          }
          this.checkAllData = i
        })
      },

      deep: true
    }
  },
  mounted() {
    if (!this.viewModel) {
      this.getList()
      this.defaultColumnInit()
      this.returnColumn()
    }
  },
  beforeDestroy() {
    this.visible = false
  },
  methods: {
    // 获取列表
    defaultColumnInit() {
      const localData = this.getLocalStorage()
      const { left, center, right } = localData || this.defaultColumn

      left.map((prop) => {
        this.checkList.push(prop)
        const column = this.tableColumnList.find((item) => item.prop === prop)
        column && this.leftColumnList.push(column)
      })
      center.map((prop) => {
        this.checkList.push(prop)
        const column = this.tableColumnList.find((item) => item.prop === prop)
        column && this.columnList.push(column)
      })
      right.map((prop) => {
        this.checkList.push(prop)
        const column = this.tableColumnList.find((item) => item.prop === prop)
        column && this.rightColumnList.push(column)
      })
      this.saveLocalStorage()
    },
    async getList(params) {
      this.colList = this.defaultList
      this.defaultCheck()
    },
    // 全选
    checkAll(val) {
      this.colList.forEach((item) => {
        this.handleCheckGroupAllChange(val, item)
        item.status = val
      })
      if (!val) {
        this.checkList = []
      }
    },
    // 全选检查
    defaultCheck() {
      this.$nextTick(() => {
        this.colList.forEach((item) => {
          this.handleCheckGroupAll(item)
        })
      })
    },
    deleteArrayItemForIndex(arr, index) {
      if (index === -1) {
        return
      }
      return arr.splice(index, 1)
    },
    // 组全选
    handleCheckGroupAllChange(val, item) {
      if (val) {
        item.children.map((column) => {
          if (this.checkList.indexOf(column.name) === -1) {
            this.checkList.push(column.name)
            this.insertColumn(column.name)
          }
        })
      } else {
        item.children.map((column) => {
          this.deleteArrayItemForIndex(this.checkList, this.checkList.indexOf(column.name))
          this.removeColumn(column.name)
        })
      }
    },
    // 组全选状态
    handleCheckGroupAll(item) {
      let flag = 1
      item.children.map((column) => {
        if (this.checkList.indexOf(column.name) === -1) {
          this.removeColumn(column.name)
          flag = 0
        } else {
          this.insertColumn(column.name)
        }
      })
      item.status = flag
    },
    // 发送数据
    async setTheadList() {
      // 数组变化调用接口保存全部数据
      const params = JSON.parse(JSON.stringify(this.colList))
      var arr = []
      params.forEach((item) => {
        item.status = item.status ? 1 : 0
        arr.push(...item.children)
      })
    },
    clearAll() {
      this.checkList = []
      this.checkAll(false)
    },
    closeColumn(name) {
      this.deleteArrayItemForIndex(this.checkList, this.checkList.indexOf(name))
      this.removeColumn(name)
      this.defaultCheck()
    },
    insertColumn(name) {
      const column = this.tableColumnList.find((item) => item.prop === name)

      if (!this.leftColumnList.find((item) => item.prop === name) && !this.rightColumnList.find((item) => item.prop === name) && !this.columnList.find((item) => item.prop === name)) {
        this.columnList.push(column)
      }
    },
    removeColumn(name) {
      if (this.leftColumnList.length && this.leftColumnList.find((item) => item.prop === name)) {
        const columnIndex = this.leftColumnList.findIndex((item) => item.prop === name)
        columnIndex > -1 && this.leftColumnList.splice(columnIndex, 1)
      }
      if (this.columnList.length && this.columnList.find((item) => item.prop === name)) {
        const columnIndex = this.columnList.findIndex((item) => item.prop === name)
        columnIndex > -1 && this.columnList.splice(columnIndex, 1)
      }
      if (this.rightColumnList.length && this.rightColumnList.find((item) => item.prop === name)) {
        const columnIndex = this.rightColumnList.findIndex((item) => item.prop === name)
        columnIndex > -1 && this.rightColumnList.splice(columnIndex, 1)
      }
      // column.status = false
    },
    returnColumn(leftColumnList = '', columnList = '', rightColumnList = '') {
      const leftColumn = leftColumnList || this.leftColumnList
      const centerColumn = columnList || this.columnList
      const rightColumn = rightColumnList || this.rightColumnList

      leftColumn.map((item) => {
        item.fixed = true
      })
      centerColumn.map((item) => {
        item.fixed = false
      })
      rightColumn.map((item) => {
        item.fixed = 'right'
      })
      this.$emit('handleTableColumn', [...leftColumn, ...centerColumn, ...rightColumn])
    },
    ok() {
      this.returnColumn()
      this.saveLocalStorage()
      this.visible = false
    },
    saveLocalStorage() {
      const columnData = {
        left: [],
        center: [],
        right: []
      }
      this.leftColumnList.map(({ prop }) => {
        prop && columnData.left.push(prop)
      })
      this.columnList.map(({ prop }) => {
        prop && columnData.center.push(prop)
      })
      this.rightColumnList.map(({ prop }) => {
        prop && columnData.right.push(prop)
      })
      localStorage.setItem(this.columnName, JSON.stringify(columnData))
    },
    getLocalStorage() {
      const localData = localStorage.getItem(this.columnName)

      if (localData) {
        return JSON.parse(localData)
      } else {
        return
      }
    },
    handleOpen() {
      if (!this.viewModel) {
        this.checkList = []
        this.rightColumnList = []
        this.leftColumnList = []
        this.columnList = []
        const localData = this.getLocalStorage()
        localData && this.defaultColumnInit()
      }
    },
    // 关闭弹窗
    close() {
      if (!this.viewModel) {
        this.checkList = []
        this.rightColumnList = []
        this.leftColumnList = []
        this.columnList = []
      }
      this.visible = false
      this.$emit('closeDialog', { visible: false })
    },
    defaultMounted() {
      this.getList()
      this.defaultColumnInit()
      this.returnColumn()
    },
    setColumnList({ left = [], center = [], right = [] }) {
      this.getList()
      const checkList = []
      const leftColumnList = []
      const columnList = []
      const rightColumnList = []
      left.map((prop) => {
        checkList.push(prop)
        const column = this.tableColumnList.find((item) => item.prop === prop)
        column && leftColumnList.push(column)
      })
      center.map((prop) => {
        checkList.push(prop)
        const column = this.tableColumnList.find((item) => item.prop === prop)
        column && columnList.push(column)
      })
      right.map((prop) => {
        checkList.push(prop)
        const column = this.tableColumnList.find((item) => item.prop === prop)
        column && rightColumnList.push(column)
      })
      this.$set(this, 'checkList', checkList)
      this.$set(this, 'leftColumnList', leftColumnList)
      this.$set(this, 'columnList', columnList)
      this.$set(this, 'rightColumnList', rightColumnList)
      this.defaultCheck()
      this.returnColumn(leftColumnList, columnList, rightColumnList)
    },
    getColumnList() {
      const column = {
        left: [],
        center: [],
        right: []
      }
      column.left = this.leftColumnList.map((item) => item.prop)
      column.center = this.columnList.map((item) => item.prop)
      column.right = this.rightColumnList.map((item) => item.prop)

      return column
    }
  }
}
</script>

<style scoped lang="scss">
.custom-column-button {
  display: flex;
  align-items: center;
}
.bi-column-container {
  display: flex;
  justify-content: space-between;

  .checkbox-container {
    .box-card-header {
      display: flex;
      justify-content: space-between;
      line-height: 20px;
      height: 20px;
      // padding: 6px 8px;
    }
    .checkbox-title {
      cursor: pointer;
      height: 36px;
      line-height: 22px;
      font-size: 14px;
      font-weight: 500;
      background-color: #f7f8fa;
      color: #333;
      position: relative;
      padding-left: 12px;
      margin-top: 0;
      margin-bottom: 16px;
      border-radius: 4px;
      align-items: center;
      display: flex;
      & + p {
        margin: 0;
      }
    }
    .el-checkbox-group {
      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;

      margin-bottom: 0;
      padding-left: 12px;

      .el-checkbox {
        width: 190px !important;
        display: block;
        float: left;
        margin: 0 !important;
        min-height: 38px;
        max-height: 58px;
        line-height: 20px;
      }
    }
  }
  .column-container {
    margin-left: 16px;
    width: 254px;
    flex: 0 0 254px;

    .column-title {
      display: flex;
      justify-content: space-between;
      line-height: 20px;
      .el-button {
        padding: 0;
      }
    }
    .column-group-title {
      font-size: 14px;
      color: #323335;
      margin: 0 0 8px 0;
    }
    .column-configurable {
      .list-group {
        min-height: 20px;
        margin-bottom: 14px;
        span {
          display: block;
          min-height: 20px;
        }
      }
      .selected-column-item {
        cursor: move;
        user-select: none;
        height: 28px;
        background: #f2f3f5;
        border-radius: 4px;
        line-height: 28px;
        padding: 0 12px;
        margin-top: 0;
        display: flex;
        align-items: center;
        color: #323335;
        font-size: 14px;
        &:not(:first-child) {
          margin-top: 8px;
        }
        &.ghost {
          opacity: 0.5;
          background: #bff3e4;
        }
        i {
          font-size: 16px;
        }
        .column-name {
          // width: 20px;
          flex-grow: 2;
          margin-left: 8px;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
        .column-close {
          display: none;
          cursor: pointer;
          transition: all 0.3s;
        }
        &:hover {
          .column-close {
            display: inline-block;
          }
        }
      }
    }
  }
}
</style>
<style lang="scss">
.bi-column-dialog {
  .el-card__header {
    background-color: #f7f8fa;
    // border: #e0e0e0 1px solid;
    box-sizing: border-box;
    line-height: 22px;
    padding: 8px 12px;
    // border-radius: 4px 4px 0 0;
    font-weight: 600;
    color: #333;
  }
  .el-card__body {
    padding: 16px;
    height: 395px;
    box-sizing: border-box;
    overflow-y: auto;
  }
}
</style>