<template>
  <div class="crud-opts">
    <span class="crud-opts-left">
      <!--左侧插槽-->
      <slot name="left"/>
      <el-button
        v-if="crud.optShow.add"
        v-permission="permission.add"
        class="filter-item"
        size="mini"
        type="primary"
        icon="el-icon-plus"
        @click="crud.toAdd"
      >
        新增
      </el-button>
      <el-button
        v-if="crud.optShow.edit"
        v-permission="permission.edit"
        class="filter-item"
        size="mini"
        type="success"
        icon="el-icon-edit"
        :disabled="crud.selections.length !== 1"
        @click="crud.toEdit(crud.selections[0])"
      >
        修改
      </el-button>
      <el-button
        v-if="crud.optShow.del"
        slot="reference"
        v-permission="permission.del"
        class="filter-item"
        type="danger"
        icon="el-icon-delete"
        size="mini"
        :loading="crud.delAllLoading"
        :disabled="crud.selections.length === 0"
        @click="toDelete(crud.selections)"
      >
        删除
      </el-button>
      <el-button
        v-if="crud.optShow.download"
        :loading="crud.downloadLoading"
        :disabled="!crud.data.length"
        class="filter-item"
        size="mini"
        type="warning"
        icon="el-icon-download"
        @click="crud.doExport"
      >导出</el-button>
      <!--右侧-->
      <slot name="right"/>
    </span>
    <el-button-group class="crud-opts-right">
      <el-button
        size="mini"
        plain
        type="info"
        icon="el-icon-search"
        @click="toggleSearch()"
      />
      <el-button
        size="mini"
        icon="el-icon-refresh"
        @click="crud.refresh()"
      />
      <el-popover
        placement="bottom-end"
        width="150"
        trigger="click"
      >
        <el-button
          slot="reference"
          size="mini"
          icon="el-icon-s-grid"
        >
          <i
            class="fa fa-caret-down"
            aria-hidden="true"
          />
        </el-button>
        <el-checkbox
          v-model="allColumnsSelected"
          :indeterminate="allColumnsSelectedIndeterminate"
          @change="handleCheckAllChange"
        >
          全选
        </el-checkbox>
        <el-checkbox
          v-for="item in tableColumns"
          :key="item.property"
          v-model="item.visible"
          @change="handleCheckedTableColumnsChange(item)"
        >
          {{ item.label }}
        </el-checkbox>
      </el-popover>
      <el-button
        size="mini"
        type="warning" plain
        @click="postToTableConfig()"
      ><span>保存</span></el-button>
    </el-button-group>
  </div>
</template>
<script>
import CRUD, {crud} from '@crud/crud'
import crudTableConfig from '@/api/tableConfig'
import Sortable from 'sortablejs'

function sortWithRef(src, ref) {
  const result = Object.assign([], ref)
  let cursor = -1
  src.forEach(e => {
    const idx = result.indexOf(e)
    if (idx === -1) {
      cursor += 1
      result.splice(cursor, 0, e)
    } else {
      cursor = idx
    }
  })
  return result
}

export default {
  mixins: [crud()],
  props: {
    permission: {
      type: Object,
      default: () => {
        return {}
      }
    },
    ignoreColumns: {
      type: Array,
      default: () => {
        return []
      }
    },
    tableKey: {
      type: String,
      default: () => {
        return ''
      }
    }
  },
  data() {
    return {
      hiddenColumns: [],
      table_configs: [],
      table_configs_xs: [],
      tableColumns: [],
      allColumnsSelected: true,
      allColumnsSelectedIndeterminate: false,
      tableUnwatcher: null,
      // 忽略下次表格列变动
      ignoreNextTableColumnsChange: false
    }
  },
  watch: {
    'crud.props.table'() {
      this.updateTableColumns()
      this.tableColumns.forEach(column => {
        //选中框

      })
    },
    'crud.props.table.store.states.columns'() {
      this.updateTableColumns()
    }
  },
  created() {
    this.crud.updateProp('searchToggle', true)
  },
  mounted() {
    //初始化数据
    this.columnDrop();
    setTimeout(() => {
      // 方法区
      this.initcolumn();
    }, 200)


  },
  methods: {

    initcolumn() {
      this.updateTableColumns()
      const strHidden = sessionStorage.getItem(this.tableKey)
      this.hiddenColumns = JSON.parse(strHidden);
      if (this.hiddenColumns) {
        const table = this.crud.props.table
        this.table_configs_xs.forEach((column, index) => {
          const vm = table.$children.find(e => e.label === column.label)
          const columnConfig = vm.columnConfig
          vm.owner.store.commit('removeColumn', columnConfig, null)
        })
        this.ignoreNextTableColumnsChange = false
        setTimeout(() => {
          // 方法区
          this.showcolumn();
        }, 200)
      }
    },
    showcolumn() {
      try {
        // 从sessionStorage安全地获取并解析hiddenColumns
        const strHidden = sessionStorage.getItem(this.tableKey)
        if (strHidden) {
          this.hiddenColumns = JSON.parse(strHidden);
        } else {
          // 如果没有找到相应的存储信息，可以初始化为空数组或相应的默认值
          this.hiddenColumns = [];
        }

        const table = this.crud.props.table
        // 优化循环中的条件判断和错误处理
        this.hiddenColumns.forEach((column, index) => {
          const vm = table.$children.find(e => e && e.prop === column.property)
          if (vm) {
            const columnConfig = vm.columnConfig;
            // 确保columnConfig存在
            if (columnConfig) {
              if (column.visible) {
                // 仅当列需要显示时，才更新其配置
                columnConfig.width = column.width;
                columnConfig.visible = column.visible;
                vm.owner.store.commit('insertColumn', columnConfig, index + 1, null);
              }
            }
          }
        });
        this.updateTableColumns();
      } catch (error) {
        console.error("处理列配置时发生错误:", error);
      }
    },
    //列拖拽
    columnDrop() {
      const wrapperTr = document.querySelector('.el-table__header-wrapper tr')
      this.sortable = Sortable.create(wrapperTr, {
        animation: 180,
        delay: 0,
        onEnd: evt => {
          // 根据中文label进行拖拉
          this.ColumnsDrop(evt.item.innerText, evt.newIndex)
        }
      })
    },

    //新加方法
    ColumnsDrop(oldText, newIndex) {
      const table = this.crud.props.table
      let myindex = -1 //空格
      let oldIndex1 = 0
      let step = -1
      let count = 0
      //
      this.tableColumns.some((column, index) => {
        if (column.visible) {
          count++
        }
      })
      // 定位拖拉中文表头位置以及在该字段之前隐藏字段数量
      this.tableColumns.some((column, index) => {
        if (column.label === oldText) {
          oldIndex1 = index
          return true
        } else {
          // 空格在字段前面
          if (step > index) {
            myindex++
          }
        }
        step++
      })
      if (myindex === -1) {
        myindex = 0
      }
      let item = this.tableColumns[oldIndex1]
      const vm = table.$children.find(e => e.prop === item.property)
      const columnConfig = vm.columnConfig
      /*this.tableColumns.splice(oldIndex1-1, 1)
      this.tableColumns.splice(myindex-1, 0, item)*/
      if (oldIndex1 < newIndex) { // 从左至右拖动
        vm.owner.store.commit('insertColumn', columnConfig, newIndex + myindex, null)
        vm.owner.store.commit('removeColumn', columnConfig, null)
      } else { //从右至左拖动
        vm.owner.store.commit('removeColumn', columnConfig, null)
        vm.owner.store.commit('insertColumn', columnConfig, newIndex + myindex, null)
      }
      // 列重新排序
      this.ignoreNextTableColumnsChange = false
    },
    updateTableColumns() {
      const table = this.crud.getTable()
      table.doLayout()
      if (!table) {
        this.tableColumns = []
        return
      }
      let cols = null
      const columnFilter = e => e && (e.type === 'default' || e.type === 'index') && e.property && this.ignoreColumns.indexOf(e.property) === -1
      const refCols = table.columns.filter(columnFilter)
      if (this.ignoreNextTableColumnsChange) {
        this.ignoreNextTableColumnsChange = false
        return
      }
      this.ignoreNextTableColumnsChange = false
      const columns = []
      const fullTableColumns = table.$children.map(e => e.columnConfig).filter(columnFilter)
      cols = sortWithRef(fullTableColumns, refCols)
      cols.forEach(config => {

        const column = {
          property: config.property,
          label: config.label,
          width: config.width,
          visible: refCols.indexOf(config) !== -1
        }
        columns.push(column)
      })
      this.tableColumns = columns
      this.table_configs_xs = columns
    },
    toDelete(datas) {
      this.$confirm(`确认删除选中的${datas.length}条数据?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.crud.delAllLoading = true
        this.crud.doDelete(datas)
      }).catch(() => {
      })
    },
    handleCheckAllChange(val) {
      if (val === false) {
        this.allColumnsSelected = true
        return
      }
      this.tableColumns.forEach(column => {
        if (!column.visible) {
          column.visible = true
          this.updateColumnVisible(column)
        }
      })
      //this.postToTableConfig()
      this.allColumnsSelected = val
      this.allColumnsSelectedIndeterminate = false
    },
    handleCheckedTableColumnsChange(item) {
      let totalCount = 0
      let selectedCount = 0
      this.tableColumns.forEach(column => {
        ++totalCount
        selectedCount += column.visible ? 1 : 0
      })
      if (selectedCount === 0) {
        this.crud.notify('请至少选择一列', CRUD.NOTIFICATION_TYPE.WARNING)
        this.$nextTick(function () {
          item.visible = true
        })
        return
      }
      this.allColumnsSelected = selectedCount === totalCount
      this.allColumnsSelectedIndeterminate = selectedCount !== totalCount && selectedCount !== 0
      this.updateColumnVisible(item)
      /*const columns = []
      this.tableColumns.forEach(column => {
        if(column.visible==false){
          columns.push(column.property)
        }
        console.log("-"+column.property+"--"+column.visible)
      })
      const post_table_config = {
        value: JSON.stringify(columns),
        tableType: this.tableKey
      }

      crudTableConfig.add(post_table_config)*/
      //this.postToTableConfig();
    },
    postToTableConfig() {
      this.updateTableColumns();
      const columns = []
      this.tableColumns.forEach(column => {
        const table_config = {
          property: column.property,
          visible: column.visible,
          width: column.width,
          label: column.label
        }
        columns.push(table_config)
      })
      const post_table_config = {
        value: JSON.stringify(columns),
        tableType: this.tableKey
      }

      this.crud.loading = true
      crudTableConfig.add(post_table_config).then(res => {
        setTimeout(() => {
          // 方法区
          this.crud.loading = false
        }, 500)

      })


      sessionStorage.setItem(this.tableKey, JSON.stringify(columns));
    },
    updateColumnVisible(item) {
      const table = this.crud.props.table
      const vm = table.$children.find(e => e.prop === item.property)
      const columnConfig = vm.columnConfig
      if (item.visible) {
        // 找出合适的插入点
        const columnIndex = this.tableColumns.indexOf(item)
        vm.owner.store.commit('insertColumn', columnConfig, columnIndex + 1, null)
      } else {
        vm.owner.store.commit('removeColumn', columnConfig, null)
      }
      this.ignoreNextTableColumnsChange = true
    },
    toggleSearch() {
      this.crud.props.searchToggle = !this.crud.props.searchToggle
    }
  }
}
</script>

<style>
.crud-opts {
  padding: 4px 0;
  display: -webkit-flex;
  display: flex;
  align-items: center;
}

.crud-opts .crud-opts-right {
  margin-left: auto;
}

.crud-opts .crud-opts-right span {
  float: left;
}
</style>
