<template>
  <div class="dv-table" :class="{scrollable: scrollable, plain: plain, 'header-border': headerBorder}" :style="styles">
    <div class="dv-table-header">
      <table>
        <colgroup>
          <col v-for="(columnDefine, index) in columnDefines" :key="index" :style="{width: getWidth(columnDefine)}"/>
        </colgroup>
        <thead>
        <tr>
          <th v-for="(columnDefine, index) in columnDefines" :key="index">
            <div class="dv-table-cell" :class="[columnDefine.order]">
              {{columnDefine.title}}
              <div class="caret-wrapper" v-if="columnDefine.sortable">
                <i class="sort-caret ascending" @click="($event) => handleSortClick($event, columnDefine, 'ascending')"></i>
                <i class="sort-caret descending" @click="($event) => handleSortClick($event, columnDefine, 'descending')"></i>
              </div>
            </div>
          </th>
        </tr>
        </thead>
      </table>
    </div>
    <div class="dv-table-body-wrap">
      <dv-loading v-if="loading"></dv-loading>
      <component :is="component" :data="items" class="seamless-warp" :class-option="classOption">
        <div class="dv-table-body">
          <table>
            <colgroup>
              <col v-for="(columnDefine, index) in columnDefines" :key="index" :style="{width: getWidth(columnDefine)}"/>
            </colgroup>
            <tbody>
            <tr v-for="(item, itemIndex) in items" :key="itemIndex">
              <td v-for="(columnDefine, columnDefineIndex) in columnDefines" :key="columnDefineIndex">
                <div class="dv-table-cell" v-if="columnDefine.ranking">
                  <span class="dv-table-cell-ranking-index" :class="[`ranking-${getValue(item, columnDefine)}`]">{{getValue(item, columnDefine)|nullableValue}}</span>
                </div>
                <div class="dv-table-cell" v-else>
                  {{getValue(item, columnDefine)|nullableValue}}
                </div>
              </td>
            </tr>
            </tbody>
          </table>
        </div>
      </component>
    </div>
  </div>
</template>

<script>
import VueSeamlessScroll from 'vue-seamless-scroll';

export default {
  name: 'DvTable',
  components: {
    VueSeamlessScroll
  },
  props: {
    headerBorder: {
      type: Boolean,
      default: false
    },
    loading: {
      type: Boolean,
      default: false
    },
    plain: {
      type: Boolean,
      default: true
    },
    scrollable: {
      type: Boolean,
      default: false
    },
    height: {
      type: [String, Number]
    },
    maxHeight: {
      type: [String, Number]
    },
    minHeight: {
      type: [String, Number]
    },
    dimensions: {
      type: Array,
      required: false,
      default () {
        return [];
      }
    },
    indexes: {
      type: Array,
      default () {
        return [];
      }
    },
    items: {
      type: Array,
      default () {
        return [];
      }
    },
  },
  data() {
    return {
      width: 0
    };
  },
  computed: {
    columnDefines() {
      return [...this.dimensions, ...this.indexes];
    },
    component () {
      return this.scrollable ? 'vue-seamless-scroll' : 'div';
    },
    classOption () {
      return {
        step: 1,
        hoverStop: true,
        direction: 1,
        openWatch: true,
        singleHeight: 33,
        waitTime: 2000
      };
    },
    styles () {
      const styles = {};
      if (this.height) {
        styles.height = this.height + 'px';
      }
      if (this.minHeight) {
        styles.minHeight = this.minHeight + 'px';
      }
      if (this.maxHeight) {
        styles.maxHeight = this.maxHeight + 'px';
      }
      return styles;
    }
  },
  methods: {
    handleSortClick (event, column, givenOrder) {
      event.stopPropagation();
      const order = column.order === givenOrder ? null : givenOrder;
      this.$set(column, 'order', order);
      this.$emit('sortChange', {
        prop: column.name,
        order: order
      });
    },
    getWidth (item) {
      if (item.width) {
        return item.width + '%';
      }
      return this.width;
    },
    computeWidth () {
      let definedWidth = 0;
      let count = 0;
      this.dimensions.forEach(_ => {
        if (_.width) {
          count++;
          definedWidth += _.width ;
        }
      });
      this.indexes.forEach(_ => {
        if (_.width) {
          count++;
          definedWidth += _.width ;
        }
      });
      const fullWidth = 100;
      this.width = ((fullWidth - definedWidth) / (this.dimensions.length + this.indexes.length - count)) + '%';
    },
    getValue (item, index) {
      let value = item[index.name];

      if (index.formatter) {
        value = index.formatter(value);
      }
      if (index.fix !== undefined) {
        return parseFloat(value).toFixed(index.fix);
      }
      return value;
    }
  },
  mounted() {
    this.computeWidth();
  }
};
</script>
