/* eslint-disable no-restricted-syntax */ /* eslint-disable guard-for-in */
<template>
  <div>
    <div style="height:5px"></div>
    <div class="d-flex justify-content-between table-title">
      <div class="p-2" v-if="!hideSearch">
        <input v-model="searchItem" class="form-control" placeholder="Search...." />
      </div>
      <div class="p-2" v-if="title">
        <h2>{{ title }}</h2>
      </div>
      <div class="p-2">
        <div class="d-flex flex-row">
          <div class="p2" v-if="showColumnChooser">
            <div
              class="btn btn-primary myBackground btn-width cursor-pointer"
              data-toggle="modal"
              data-target="#myModal"
            >Column Chooser</div>
            <div class="col-md-12">
              <div id="myModal" class="modal fade" role="dialog">
                <div class="modal-dialog modal-lg">
                  <!-- Modal content-->
                  <div class="modal-content">
                    <div class="modal-header">
                      <h5>Column Chooser</h5>
                      <button type="button" class="close" data-dismiss="modal">&times;</button>
                    </div>
                    <div style="margin-left:50px; margin-right:50px;margin-bottom:50px;">
                      <ListViewControl :items="allColumn" @checkItem="checkItem" />
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <div class="p2" v-if="selectedItems.length > 0">
            <div
              class="btn btn-primary myBackground btn-width cursor-pointer"
              @click="onClearSelected()"
            >Clear Selected</div>
          </div>
          <div class="p2" v-if="showNew">
            <div class="btn btn-primary myBackground btn-width cursor-pointer" @click="onNew()">New</div>
          </div>
        </div>
      </div>
    </div>
    <div style="height:5px"></div>
    <div v-if="items && items.length > 0" class="table-responsive">
      <table
        id="table"
        :class="{ 'table table-hover': 1 === 1, 'table-sm': compact, 'table-bordered': bordered }"
      >
        <thead>
          <tr class="dnd-moved">
            <th v-for="(column, c) in Columns" :key="c">
              <div
                @click="sortBy(column)"
                @mouseover="hover = c"
                @mouseleave="hover = -1"
                :class="{ active: hover === c }"
              >
                <div class="d-flex bd-highlight">
                  <div
                    v-if="displayHeaders.length === 0"
                    class="p-2 w-100 bd-highlight"
                  >{{ column | toProper }}</div>
                  <div
                    v-else
                    class="p-2 w-100 bd-highlight"
                  >{{ displayHeaders[c] !== "" ? displayHeaders[c] : column | toProper }}</div>
                  <div class="p-2 flex-shrink-1 bd-highlight">
                    <img
                      src="../../../public/img/sort-up.png"
                      height="8px;"
                      v-if="sortKey === column && reverse"
                    />
                    <img
                      src="../../../public/img/sort-down.png"
                      height="8px;"
                      v-if="sortKey === column && !reverse"
                    />
                  </div>
                </div>
              </div>
            </th>
            <th v-if="showCustomAction"></th>
            <th v-if="editable"></th>
            <th v-if="deleteable"></th>
          </tr>
        </thead>
        <tbody class="my-table">
          <tr
            v-for="(item, i) in DisplayItems"
            :key="i"
            @click="onRowClick(item, i)"
            :class="{ selected: isSelected(i), 'cursor-pointer': allowSelect }"
          >
            <td v-for="(column, c) in Columns" :key="c">
              <div
                v-if="displayFormats.length === 0"
              >{{ isObject(item[column]) ? item[column].display : item[column] }}</div>
              <div v-else-if="displayFormats.length > 0 && displayFormats[c] === 'date'">
                <div
                  v-if="item[column] !== '0001-01-01T00:00:00'"
                >{{ isObject(item[column]) ? item[column].display : item[column] | toDate }}</div>
              </div>
              <div
                v-else-if="displayFormats.length > 0 && displayFormats[c] === 'money'"
              >{{ isObject(item[column]) ? item[column].display : item[column] | toCurrency }}</div>
              <div v-else-if="displayFormats.length > 0 && displayFormats[c] === 'image'">
                <img :src="item[column]" style="height:100px; width:100px; object-fit: cover;" />
              </div>
              <div v-else>{{ isObject(item[column]) ? item[column].display : item[column] }}</div>
            </td>
            <td v-if="showCustomAction" class="my-width">
              <button
                type="button"
                class="btn my-btn"
                @click="onCustomClick(item)"
              >{{ CustomActionHeading }}</button>
            </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" v-if="showPager">
        <div class="p-1">
          {{
          currentPage +
          " / " +
          PageCount +
          (!hideItemCount ? " - (" + FilteredItems.length + " items)" : "")
          }}
        </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>
    <div v-else>
      <Alert :text="'No items found ^-^'" :type="'INFO'" />
    </div>
  </div>
</template>

<script>
import _ from "lodash";
import ItemsPerPageList from "../../assets/staticData/itemsPerPage";
import BasePagination from "./basePagination.vue";
import Alert from "./alert.vue";
import ListViewControl from "./listViewControl.vue";

export default {
  components: {
    BasePagination,
    Alert,
    ListViewControl
  },
  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;
    }
    this.getInitColumn();
  },
  props: {
    compact: {
      default: true
    },
    allowSelect: {
      default: true
    },
    allowMultipleSelect: {
      default: false
    },
    hideSearch: {
      default: false
    },
    showNew: {
      default: true
    },
    items: undefined,
    editable: {
      default: false
    },
    deleteable: {
      default: false
    },
    columnCount: {
      default: 6
    },
    showPager: {
      default: true
    },
    title: {
      default: undefined
    },
    sortKey: {
      default: "id"
    },
    hideItemCount: {
      default: false
    },
    currentPage: {
      default: 1
    },
    bordered: {
      default: true
    },
    striped: {
      default: true
    },
    showColumnChooser: {
      default: true
    },
    displayColumns: {
      default: []
    },
    displayFormats: {
      default: []
    },
    displayHeaders: {
      default: []
    },
    showCustomAction: {
      default: false
    },
    CustomActionHeading: {
      default: ""
    },
    CustomActionCondition: {
      default: ""
    }
  },
  data() {
    return {
      hover: -1,
      selectedItems: [],
      showControl: false,
      sortKey: "",
      reverse: false,
      searchItem: "",
      visibleItemsPerPageCount: 20,
      itemsPerPageList: ItemsPerPageList,
      visibleColumn: [],
      allColumn: []
    };
  },
  methods: {
    checkItem(column, show) {
      const list = [];
      for (const i in this.allColumn) {
        const item = this.allColumn[i];
        if (item && item.column === column) {
          item.show = show;
        }
        list.push(item);
      }
      this.allColumn = list;
    },
    getInitColumn() {
      const list = [];
      const listAll = [];
      if (this.items) {
        for (const i in Object.keys(this.items)) {
          const item = this.items[i];
          for (const o in Object.keys(item)) {
            if (
              !listAll.includes(Object.keys(item)[o]) &&
              !Array.isArray(Object.values(item)[o])
            ) {
              const columnName = Object.keys(item)[o];
              if (!listAll.some(x => x.column === columnName)) {
                listAll.push({
                  column: columnName,
                  show: _.filter(listAll, x => x.show).length < this.columnCount
                });
              }
            }
          }
        }
      }
      this.allColumn = listAll;
    },
    onClearSelected() {
      this.selectedItems = [];
      this.$emit("onClearSelected");
    },
    isSelected(i) {
      const ind = this.getActualIndex(i);
      return _.some(this.selectedItems, x => x === ind);
    },
    onNew() {
      this.$emit("onNew");
    },
    isObject(item) {
      return !!item && item.constructor === Object;
    },
    isDate(item) {
      return !!item && item.constructor === Date;
    },
    isDecimal(item) {
      if (!!item && item.constructor === Number && item.indexOf(".") > 0) {
        return true;
      }
      return false;
    },
    isImage(item) {
      return (
        !!item &&
        item.constructor === String &&
        item.length > 9 &&
        item.substring(0, 9) === "data:image"
      );
    },
    onEdit(item) {
      this.$emit("onEdit", item);
    },
    onDelete(item) {
      this.$emit("onDelete", item);
    },
    onCustomClick(item) {
      this.$emit("onCustomClick", item);
    },
    onRowClick(item, i) {
      const ind = this.getActualIndex(i);
      if (_.some(this.selectedItems, x => x === ind)) {
        this.selectedItems = this.selectedItems.filter(x => x !== ind);
      } else {
        if (!this.allowMultipleSelect) {
          this.selectedItems = [];
        }
        this.selectedItems.push(item);
      }
      this.$emit("onRowClick", this.selectedItems);
    },
    getActualIndex(index) {
      return (this.currentPage - 1) * this.visibleItemsPerPageCount + index;
    },
    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;
      }
    },
    inArray(array, value) {
      const lenght = array.length;
      for (let i = 0; i < lenght; i++) {
        if (array[i] === value) return true;
      }
      return false;
    }
  },
  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 listColumns = [];
      if (!this.allColumn || this.allColumn.length === 0) {
        this.getInitColumn();
      }
      if (this.displayColumns.length > 0) {
        for (let i = 0; i < this.displayColumns.length; i++) {
          listColumns.push(this.displayColumns[i]);
        }
      } else {
        const list = _.filter(this.allColumn, x => x.show);
        for (const i in list) {
          const item = list[i];
          if (item) {
            listColumns.push(item.column);
          }
        }
      }
      return listColumns;
    },
    AllColumns() {
      const list = [];
      if (this.items) {
      }
      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);
    },
    GetAllColumn() {}
  }
};
</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-striped > tbody > tr:nth-child(2n + 1) > td,
.table-striped > tbody > tr:nth-child(2n + 1) > th {
  background-color: rgba(225, 225, 225, 0.8);
}
.active {
  background-color: rgba(255, 255, 255, 0.5);
  cursor: pointer;
}
.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);
}
.my-border {
  border: solid 3px silver;
}
.selected {
  background-color: rgba(96, 203, 235, 0.5);
  border: white 2px double;
}
.selected:hover {
  background-color: rgba(96, 203, 235, 0.85);
}
.btn-width {
  width: 125px;
}
.table-title {
  padding: 5px;
  border: rgba(200, 200, 200, 0.66) double 2px;
  border-radius: 5px;
  background-color: rgba(96, 203, 235, 0.25);
}
.table-title:hover {
  background-color: rgba(96, 203, 235, 0.4);
}
.table-header {
  background-color: rgba(200, 200, 200, 0.66);
}
.my-table {
  border: rgba(150, 150, 150, 0.75) 3px double;
}
</style>
