<template>
  <div class="table-layout">
    <!-- 表头 -->
    <ul class="t-header" :class="{'bottom-line':showLine}">
      <!-- 复选框 -->
      <div
        v-show="selection && !isAllSelected"
        class="checkbox inactive"
        @click="onClickSelectAll"
      >
      </div>
      <img
        v-show="isAllSelected"
        class="checkbox active"
        @click="onClickSelectAll"
        src="@/assets/images/icons/checkbox.png"
        draggable="false"
      />
      <!-- 表头各项 -->
      <li
        v-for="(headerItem,i) in header"
        :key="i"
        :style="{
          textAlign: headerItem.textAlign,
          width: headerItem.width ? headerItem.width+'px' : (100/header.length)+'%'
        }"
      >
        <!-- 名字叫header的作用域插槽，通过headerItem作用域提供表头各项 -->
        <slot :headerItem='headerItem' name='header'></slot>
      </li>
    </ul>
    <!-- 表格内容区域 -->
    <div
      class="t-con"
      v-infinite-scroll="requestMoreData"
      :infinite-scroll-disabled="!canRequestMoreData"
      ref="t-con"
      :style="`margin-right: ${hasScrollBar ? -6 : 0}px`"
    >
      <!-- 表格每一行 -->
      <ul
        class="t-item"
        :class="{'bottom-line': showLine}"
        v-for="(lineData, i) in data"
        :key="i"
      >
        <!-- 复选框 -->
        <div
          v-show="selection && !selectedIdList.some(id => id === lineData.id)"
          class="checkbox inactive"
          @click="selectItem(lineData, i)"
        />
        <img
          v-show="selection && selectedIdList.some(id => id === lineData.id)"
          class="checkbox active"
          @click="selectItem(lineData, i)"
          src="@/assets/images/icons/checkbox.png"
          draggable="false"
        />
        <!-- 表格各项 -->
        <li
          v-for="(headerItem, j) in header"
          :key='j'
          :style="{
            textAlign: lineData.textAlign,
            width: headerItem.width ? headerItem.width + 'px' : (100 / header.length) + '%'
          }"
          :class="{
            themetxt: headerItem.fontweight,
            showWhenHover: headerItem.showWhenHover
          }"
          :title="headerItem.key === 'name' ? lineData[headerItem.key] : ''"
        >
          <!-- 名字叫tableItem的作用域插槽，通过itemData作用域把这一项表格数据向外暴露，通过lineData作用域把每一行向外暴露，通过headerItem作用域把这一项对应的表头项向外暴露 -->
          <slot
            :itemData='lineData[headerItem.key]'
            :lineData="lineData"
            :headerItem='headerItem'
            name='tableItem'
          ></slot>
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import { mapState } from 'vuex'

export default {
  props: {
    canRequestMoreData: {
      type: Boolean,
      default: true
    },
    data: {
      type: Array,
      default: Array
    },
    /**
     * 表头数据：各列名称和配置
     * fontweight: Boolean，某一列是否是关键列,会加粗显示
     * showWhenHover: Boolean,是否只在hover到这一行时才显示这一列在该行的数据
     * canclick: Booean, 是否可点击进行各种操作
     * width: Number,该列宽度
     * textAlign: css属性值
     */
    header: {
      type: Array,
      default: Array
    },
    // 是否显示复选框
    selection: {
      type: Boolean,
      defaut: false
    },
    // 是否显示每行之间的分隔线
    showLine: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      hasScrollBar: false,
      selectedIdList: [],
    }
  },
  computed: {
    isAllSelected() {
      if (this.data && this.data.length > 0) {
        return this.data.length === this.selectedIdList.length
      } else {
        return false
      }
    },
  },
  watch: {
    data: {
      handler(v) {
        const newSelectedIdList = []
        for (const selectedId of this.selectedIdList) {
          if (this.data.some((item) => {
            return item.id === selectedId
          })) {
            newSelectedIdList.push(selectedId)
          }
        }
        this.selectedIdList = newSelectedIdList
      },
      deep: true,
    }
  },
  methods: {
    onClickSelectAll() {
      if (this.isAllSelected) {
        this.selectedIdList = []
      } else {
        this.selectedIdList = []
        this.data.forEach(item => {
          this.selectedIdList.push(item.id)
        })
      }
      this.emitSelectionChange()
    },
    requestMoreData() {
      this.$emit('request-more-data')
    },
    emitSelectionChange () {
      let arr = this.data.filter(item => {
        return this.selectedIdList.some((selectedId) => {
          return selectedId === item.id
        })
      })
      this.$emit('selection-change', arr)
    },
    selectItem (selectedItem, i) {
      const idx = this.selectedIdList.findIndex((alreadySelectedId) => {
        return alreadySelectedId === selectedItem.id
      })
      if (idx > -1) {
        this.selectedIdList.splice(idx, 1)
      } else {
        this.selectedIdList.push(selectedItem.id)
      }
      this.emitSelectionChange()
    }
  },
  mounted () {
    const resizeObserver = new ResizeObserver((entries) => {
      if (entries[0].target.clientHeight < entries[0].target.scrollHeight) {
        this.hasScrollBar = true
      } else {
        this.hasScrollBar = false
      }
       
    })
    resizeObserver.observe(this.$refs['t-con'])
  },
}
</script>

<style lang="less" scoped>
.table-layout {
  width: 100%;
  color: #777;
  font-size: 14px;

  .checkbox {
    display: inline-block;
    margin-right: 20px;
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    cursor: pointer;
    user-select: none;
  }
  .inactive {
    border-radius: 2px;
    border: 1px solid #D5D8DE;
  }
  .checkbox.active {
  }

  .t-header {
    display: flex;
    align-items: center;
    width: 100%;
    padding: 15px 16px 15px 16px;
    background-color: #F5F7FA;
    color: #646566;
    line-height: 19px;
    position: relative; // 为了设置z-index
    z-index: 1; // 为了避免.t-con向下滚动后覆盖本元素。因为.t-con的margin-top是负值。
    li {
      text-align: left;
      margin-right: 20px;
      flex-grow: 1;
    }
  }

  // 表格内容
  .t-con {
    padding-top: 49px; // 为了能上下滚动，overflow的值不能是visible，导致此元素是个BFC，导致绝对定位的tip在第一行无法显示在此元素区域外，只好让此元素具有padding-top以供第一行的tip显示。
    margin-top: -49px;
    height: calc(100vh - 325px); // 必须指定高度，element-ui的无限滚动指令才能生效
    overflow: auto;
    .t-item {
      display: flex;
      align-items: center;
      width: 100%;
      padding: 10px 16px 10px 16px;
      .showWhenHover {
        visibility: hidden;
      }
      &:hover {
        background: #F7F7F7;
        .showWhenHover {
          visibility: visible;
        }
        &[active-txt] {
          // 关键列，会加粗显示且有hover效果。
          >.themetxt {
            span {
              word-break: break-all;
              font-weight: bold;

              &:hover {
                color: #1FE4DC !important;
                cursor: pointer;
              }
            }
          }
        }
      }
      li {
        text-align: left;
        display: inline-block;
        margin-right: 20px;
        flex-grow: 1;
        .textItem {
          color: #323233;
        }
      }
    }

    .bottom-line {
      min-height: 50px;
      border-bottom: 1px solid rgba(#202020, 0.1);
    }
  }
}
</style>
