/* eslint-disable no-restricted-syntax */
/* eslint-disable guard-for-in */
<template>
  <div>
    <div class="d-flex justify-content-between" v-if="!hideSearch">
      <div class="p-2">
        <input v-model="searchItem" class="form-control" placeholder="Search ..." />
      </div>
    </div>
    <table id="table" class="table table-bordered table-hover">
      <thead>
        <tr class="dnd-moved">
          <th v-for="(column, c) in Columns" :key="c">
            <div @click="sortBy(column)">{{ column }}</div>
          </th>
          <th v-if="editable"></th>
          <th v-if="deleteable"></th>
        </tr>
      </thead>
      <tbody>
        <tr
          v-for="(item, i) in DisplayItems"
          :key="i"
          class="text-left dnd-moved"
          @click="onRowClick(item)"
        >
          <td
            v-for="(column, c) in Columns"
            :key="c"
          >{{ isObject(item[column]) ? item[column].display : item[column] }}</td>
          <td v-if="editable" class="my-width">
            <button type="button" class="btn my-btn" @click="onEdit(item)">Edit</button>
          </td>
          <td v-if="deleteable" class="my-width">
            <button type="button" class="btn my-btn" @click="onDelete(item)">Delete</button>
          </td>
        </tr>
      </tbody>
    </table>
    <div class="d-flex justify-content-between">
      <div class="p-1">{{ currentPage + ' / ' + PageCount }}</div>
      <div class="p-1">
        <BasePagination
          :currentPage="currentPage"
          :pageCount="PageCount"
          @nextPage="pageChangeHandle('next')"
          @previousPage="pageChangeHandle('previous')"
          @loadPage="pageChangeHandle"
        />
      </div>
      <div class="p-2">
        <div class="d-flex flex-row">
          <div>
            <select
              class="form-control"
              v-model="visibleItemsPerPageCount"
              @change="onChangeItemsPerPage()"
            >
              <option v-for="(item, i) in itemsPerPageList" :key="i">{{ item }}</option>
            </select>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import _ from 'lodash';
import ItemsPerPageList from '../../assets/staticData/itemsPerPage';
import BasePagination from './basePagination.vue';

export default {
  components: {
    BasePagination,
  },
  mounted() {
    try {
      // to assign initial value to itemsPerPage
      if (this.itemsPerPageList && this.itemsPerPageList.length > 0) {
        const [startItem] = this.itemsPerPageList;
        this.visibleItemsPerPageCount = startItem;
      }
    } catch (error) {
      throw error;
    }
  },
  props: {
    hideSearch: {
      default: false,
    },
    items: undefined,
    editable: {
      default: false,
    },
    deleteable: {
      default: false,
    },
    columnsCount: {
      default: 6,
    },
  },
  data() {
    return {
      showControl: false,
      sortKey: '',
      reverse: false,
      searchItem: '',
      itemsPerPageList: ItemsPerPageList,
      visibleItemsPerPageCount: 0,
      currentPage: 1,
    };
  },
  methods: {
    isObject(item) {
      return !!item && item.constructor === Object;
    },
    onEdit(item) {
      this.$emit('onEdit', item);
    },
    onDelete(item) {
      this.$emit('onDelete', item);
    },
    onRowClick(item) {
      this.$emit('onRowClick', item);
    },
    changeColumn(title, checked) {
      if (checked) {
        this.myColumns.push(title);
      } else {
        const ind = this.myColumns.indexOf(title);
        if (ind > -1) {
          this.myColumns.splice(ind, 1);
        }
      }
    },
    onControlVisibilityChange() {
      this.showControl = !this.showControl;
    },
    sortBy(sortKey) {
      this.reverse = this.sortKey === sortKey ? !this.reverse : false;
      this.sortKey = sortKey;
    },
    async pageChangeHandle(value) {
      console.log(value);
      switch (value) {
        case 'next':
          this.currentPage += 1;
          break;
        case 'previous':
          this.currentPage -= 1;
          break;
        default:
          this.currentPage = value;
      }
    },
    onChangeItemsPerPage() {
      if (this.currentPage !== 1) {
        this.currentPage = 1;
      }
    },
  },
  computed: {
    ListWidth() {
      if (this.showControl) {
        return 'col-md-9';
      }
      return 'col-md-12';
    },
    SortDirection() {
      return this.reverse ? 'desc' : 'asc';
    },
    PageCount() {
      return this.visibleItemsPerPageCount !== 0
        ? Math.ceil(this.FilteredItems.length / this.visibleItemsPerPageCount)
        : 1;
    },
    Columns() {
      const list = [];
      if (this.items) {
        for (const i in Object.keys(this.items)) {
          const item = this.items[i];
          for (const o in Object.keys(item)) {
            if (
              !list.includes(Object.keys(item)[o])
              && !Array.isArray(Object.values(item)[o])
            ) {
              if (list.length < this.columnsCount) {
                list.push(Object.keys(item)[o]);
              }
            }
          }
        }
      }
      return list;
    },
    FilteredItems() {
      const list = _.filter(this.items, item => Object.values(item).some(
          i => JSON.stringify(i)
              .toLowerCase()
              .indexOf(this.searchItem.toLowerCase()) > -1,
        ),);
      return _.orderBy(list, this.sortKey, this.SortDirection);
    },
    DisplayItems() {
      const list = this.FilteredItems;
      const startSlice = (this.currentPage - 1) * this.visibleItemsPerPageCount;
      let endSlice = this.currentPage * this.visibleItemsPerPageCount;
      if (endSlice > list.length) {
        endSlice = list.length;
      }
      return list.slice(startSlice, endSlice);
    },
  },
};
</script>
<style scoped>
th[draggable] a,
th[draggable] {
  cursor: move;
}
th[draggable] a:hover,
th[draggable] a {
  display: block;
  text-decoration: none;
  color: #333333;
}
.table > tbody > tr > td {
  vertical-align: middle;
}
.my-width {
  width: 20px;
}
.drag {
  background-color: rgba(0, 255, 0, 0.35);
  opacity: 0.25;
}
.dnd-drag {
  opacity: 0.25;
}
.over {
  background-color: rgba(0, 0, 255, 0.35);
}
</style>
