<style lang="less" scoped>
@import './index.less';
</style>
<template>
  <div class="list-view">
    <div @click="clickHead">
      <slot name="head" />
    </div>
    <list-body ref="tbody" :draggable="draggable" :gutter="gutter" :obj-data="objData" />
    <div @click="clickFoot">
      <slot name="foot" />
    </div>
  </div>
</template>

<script>
// import ListHead from './list-head.vue';
// import ListFoot from './list-foot.vue';
import ListBody from './list-body.vue';
import { deepClone } from '../utils/deep-clone';

export default {
  name: 'list-view',
  components: { ListBody },
  provide() {
    return {
      listRoot: this // 将本页面的对象传递给子组件
    };
  },
  props: {
    /**
     * 列表集合
     */
    data: {
      type: Array,
      default() {
        return [];
      }
    },
    /**
     * 是否可以拖拉控件
     */
    draggable: {
      type: Boolean,
      default: true
    },

    /**
     * 是否不显示hover
     */
    disabledHover: {
      type: Boolean,
      default: false
    },
    /**
     * 行高亮
     */
    highlightRow: {
      type: Boolean,
      default: true
    },

    /**
     * 行的 className 的回调方法，传入参数：
     * row：当前行数据
     *index：当前行的索引
     */
    rowClassName: {
      type: Function,
      default() {
        return '';
      }
    },

    /**
     * 元素之间的间距（单位为px）
     */
    gutter: {
      type: [Number, String],
      default: 0
    },
    /**
     * 行点击前调用的方法，可以控制是否高亮选中，方法返回true为可以选中并高亮
     */
    rowBeforeClick: {
      type: Function,
      default() {
        return true;
      }
    }
  },
  data() {
    return {
      /**
       * 当前选择的行 （-1为没有选中）
       */
      selectionRowIndex: -1,
      objData: null
    };
  },
  watch: {

    data: {
      immediate: true,
      handler(data) {
        //  console.log('---------watch---------data=',this.data)
        //  if(!this.objData || this.objData.length == 0 ){
        this.objData = this.makeObjData();
        //  }
      }
    }
  },
  methods: {
    /**
     * 构建数据
     */
    makeObjData() {
      const data = [];
      if (!this.data) {
        return data;
      }
      this.data.forEach((row, index) => {
        const newRow = deepClone(row); // todo 直接替换
        newRow._isHover = false;
        row._index = index;
        if (newRow._disabled) {
          newRow._isDisabled = newRow._disabled;
        } else {
          newRow._isDisabled = false;
        }
        /**
         * 监听的属性不能动态添加，所以这里需要先设置_highlight和_isHighlight
         */
        if (newRow._highlight) {
          newRow._isHighlight = newRow._highlight;
        } else {
          newRow._isHighlight = false;
        }
        data[index] = newRow;
      });
      return data;
    },
    /**
     * 鼠标进入后处理
     */
    handleMouseIn(_index) {
      // console.log('==========handleMouseIn=' + _index);
      if (this.disabledHover) {
        return;
      }
      if (this.objData[_index]._isHover) return;
      this.objData[_index]._isHover = true;
    },
    /**
     * 鼠标出去之后的处理
     */
    handleMouseOut(_index) {
      if (this.disabledHover) return;
      this.objData[_index]._isHover = false;
    },
    /**
     * 通用处理 highlightCurrentRow 和 clearCurrentRow
     */
    handleCurrentRow(type, _index) {
      let oldIndex = this.selectionRowIndex;
      for (const i in this.objData) {
        if (this.objData[i]._isHighlight) {
          oldIndex = parseInt(i);
          this.objData[i]._isHighlight = false;
        }
      }
      if (type === 'highlight') {
        this.objData[_index]._isHighlight = true;
        this.selectionRowIndex = _index;
      } else { // 清除当前选择的行
        this.selectionRowIndex = -1;
      }
      if (oldIndex != this.selectionRowIndex) {
        this.rowSelectedChangeEvent(oldIndex, this.selectionRowIndex);
      }

      const oldData =
        oldIndex < 0 ? null : JSON.parse(JSON.stringify(this.objData[oldIndex]));
      const newData =
        type === 'highlight' ? JSON.parse(JSON.stringify(this.objData[_index])) : null;
      this.$emit('on-current-change', newData, oldData);
    },
    /**
     * 高亮当前行
     */
    highlightCurrentRow(_index) {
      if (!this.highlightRow
      || !this.objData || this.objData.length == 0
      || this.objData.length <= _index
      || this.objData[_index]._isHighlight) {
        return;
      }
      this.handleCurrentRow('highlight', _index);
    },
    /**
     * 清除当前选择中行
     */
    clearCurrentRow() {
      if (!this.highlightRow) return;
      this.handleCurrentRow('clear');
    },
    /**
     * 点击了头部
     */
    clickHead() {
      this.$emit('on-head-click');
      this.clearCurrentRow();
    },
    /**
     * 点击了底部
     */
    clickFoot() {
      this.$emit('on-foot-click');
      this.clearCurrentRow();
    },
    /**
     * 删除行（注：会删除掉传入来数据）
     */
    deleteRow(_index) {
      // console.log('deleteRow=' + _index)
      if (this.objData) {
        this.clearCurrentRow();
        // 删除的数据
        const deleteRow = this.objData[_index];
        /**
         * 会直接删除传入来的数据
         */
        this.objData.splice(_index, 1);
        this.data.splice(_index, 1);

        // 当前选中的索引要修改
        if (this.selectionRowIndex == _index) {
          this.selectionRowIndex = -1;
        } else if (this.selectionRowIndex > _index) {
          this.selectionRowIndex -= 1;
        }

        this.$emit('on-row-delete', _index);
      }
    },
    /**
     * 点击当前行
     * 如果需要动态添加一行，并马上选择添加的行，需要要有推迟调用，如下方法
     *  var intervalId = setInterval(() => {
     *   clearInterval(intervalId);
     *      _this.clickRow(selectedIndex)
     *  }, 500)
     */
    clickCurrentRow(_index) {
      //  console.log('---------------clickCurrentRow=',_index)
      if (!this.rowBeforeClick(_index)) {
        return;
      }
      if (!this.objData[_index]) {
        return;
      }

      this.highlightCurrentRow(_index);
      this.$emit(
        'on-row-click',
        JSON.parse(JSON.stringify(this.objData[_index])),
        _index
      );
    },
    /**
     * 双击当前行
     */
    dblclickCurrentRow(_index) {
      this.highlightCurrentRow(_index);
      this.$emit(
        'on-row-dblclick',
        JSON.parse(JSON.stringify(this.objData[_index])),
        _index
      );
    },

    /**
     * 拖拉完成后处理 （注：会调换掉传入来数据）
     */
    dragAndDrop(oldIndex, newIndex) {
      // 被拖拉的行数据
      // const oldIndexData = this.objData[oldIndex];
      // // 目标行的数据
      // const newIndexData = this.objData[newIndex];
      // this.$set(this.objData, oldIndex, newIndexData);
      // this.$set(this.objData, newIndex, oldIndexData);

      /**
       * 影响传入来的数据
       */
      // 被拖拉的行数据
      const oldIndexData = this.data[oldIndex];
      // 目标行的数据
      const newIndexData = this.data[newIndex];
      this.$set(this.data, oldIndex, newIndexData);
      this.$set(this.data, newIndex, oldIndexData);

      const _this = this;
      // 因为拖拉过快，还没有来得及响应监听事件，所以这里延迟
      var intervalId = setInterval(() => {
        clearInterval(intervalId);
        _this.clickCurrentRow(newIndex);
      }, 50);
      this.$emit('on-drag-drop', oldIndex, newIndex);
      this.rowSelectedChangeEvent(oldIndex, newIndex);
    },
    /**
     * 行选择改变事件
     */
    rowSelectedChangeEvent(oldIndex, newIndex) {
      this.$emit('on-row-selected-change', oldIndex, newIndex);
    }
  }
};
</script>
