<template>
  <div class="ui-brick-wall" :class="{'is-line-wrap': lineWrap}" :style="{height: height}">
    <template v-if="innerLoading">
      <brick-wall-skeleton
        :line-wrap="lineWrap"
        :span="innerSpan"
        :col-style="colStyle"
      ></brick-wall-skeleton>
    </template>
    <template v-else>
      <ui-empty
        v-if="isEmpty"
      ></ui-empty>
      <template v-else>
        <div
          class="ui-brick-wall__row"
          v-for="(row, rowIndex) in showData"
          :key="rowIndex"
        >
          <div
            class="ui-brick-wall__col"
            v-for="(col, colIndex) in row"
            :key="colIndex"
            :style="colStyle"
          >
            <template v-if="col !== null">
              <slot name="item" :data="col" :index="(rowIndex * innerSpan) + colIndex"></slot>
            </template>
          </div>
        </div>
      </template>
    </template>
  </div>
</template>
<script>
import UiEmpty from '@huntianning/components/packages/empty'
import BrickWallSkeleton from './brick-wall-skeleton.vue'

export default {
  name: 'UiBrickWall',
  components: {
    UiEmpty,
    BrickWallSkeleton
  },
  props: {
    height: {
      type: String
    },
    /**
     * 显示加载中
    */
    loading: {
      type: Boolean
    },
    /**
     * 数据
    */
    data: {
      type: Array,
      default: () => []
    },
    /**
     * 一行显示多少个
    */
    span: {
      type: Number
    },
    /**
     * 查询数据方法
    */
    queryMethod: {
      type: Function
    },
    /**
     * 基础宽度
     * 会根据这个宽度自动计算span，如果设置了固定span，就不需要计算
    */
    baseWidth: {
      type: Number
    },
    /**
     * 是否换行
    */
    lineWrap: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      innerLoading: false,
      innerData: this.data,
      width: null
    }
  },
  computed: {
    colStyle() {
      if (this.lineWrap) {
        return
      }
      if (!this.baseWidth) {
        return
      }
      return {
        width: this.baseWidth + 'px',
        minWidth: this.baseWidth + 'px'
      }
    },
    isEmpty() {
      return !!(!this.innerData || !this.innerData.length)
    },
    innerSpan() {
      if (this.span) {
        return this.span
      }
      if (this.width && this.baseWidth) {
        return Math.floor(this.width / this.baseWidth)
      }
      return 1
    },
    showData() {
      if (this.lineWrap) {
        const data = this.innerData || []
        const last = data.length - 1
        return data.reduce((rs, v, i) => {
          const index = Math.floor(i / this.innerSpan)
          if (!rs[index]) {
            rs[index] = []
          }
          rs[index].push(v)
          if (i === last) {
            const sy = this.innerSpan * (index + 1) - (i + 1)
            if (sy > 0) {
              for (let j = 0; j < sy; j++) {
                rs[index].push(null)
              }
            }
          }
          return rs
        }, [])
      } else {
        return [this.innerData]
      }
    }
  },
  watch: {
    data(newVal) {
      this.innerData = newVal
    }
  },
  mounted() {
    this.loadData()
    window.addEventListener('resize', this.handleWindowResize)
    this.syncWidth()
  },
  methods: {
    handleWindowResize() {
      this.syncWidth()
    },
    syncWidth() {
      if (!this.lineWrap) {
        return
      }
      this.width = this.$el.clientWidth
    },
    loadData() {
      if (!this.queryMethod) {
        return
      }
      this.innerLoading = true
      this.queryMethod().then(rs => {
        this.innerData = rs
      }).finally(() => {
        this.innerLoading = false
      })
    },
    reload() {
      this.loadData()
    }
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.handleWindowResize)
  }
}
</script>
<style lang="less">
.ui-brick-wall{
  margin-top: -12px;
  margin-bottom: -12px;
  &:not(.is-line-wrap) {
    overflow: auto;
    .ui-brick-wall__col{
      padding-bottom: 0;
    }
  }
  &.is-line-wrap {
    .ui-brick-wall__col{
      flex: 1;
      min-width: 0;
    }
  }
}
.ui-brick-wall__row{
  display: flex;
  flex-direction: row;
}
.ui-brick-wall__col {
  padding: 12px;
  &:last-child{
    padding-right: 0;
  }
  &:first-child{
    padding-left: 0;
  }
}
</style>
