<template>
  <div class="items">
    <div class="tab-bg">
      <div class="wrapper">
        <div class="tab-control">
          <a v-for="(tab, index) of tabs" :key="index" @click="changeTab(tab)" :class="{ active: tab.active }">{{ tab.name }}</a>
        </div>
      </div>
    </div>
    <WorksTable v-if="activeTab.type === 'works' && activeTab.data" :works="works" :materials="materials" :mechanisms="mechanisms" :properties="properties" @graphql-mutation="graphqlMutation" />
    <MaterialsTable v-if="activeTab.type === 'materials' && activeTab.data" :materials="materials" :properties="properties" @graphql-mutation="graphqlMutation" />
    <MechanismsTable v-if="activeTab.type === 'mechanisms' && activeTab.data" :mechanisms="mechanisms" :properties="properties" @graphql-mutation="graphqlMutation" />
  </div>
</template>

<script>
import WorksTable from '@/components/WorksTable.vue';
import MaterialsTable from '@/components/MaterialsTable.vue';
import MechanismsTable from '@/components/MechanismsTable.vue';
import { API } from 'aws-amplify';
import { listUserWorks, listUserMaterials, listUserMechanisms } from "../graphql/queries";
import * as Mutation from '../graphql/mutations';

export default {
  name: "TablePage",
  components: {
    WorksTable,
    MaterialsTable,
    MechanismsTable
  },
  created() {
    this.listUserItems({ listUserWorks }, 'works');
    this.listUserItems({ listUserMaterials }, 'materials');
    this.listUserItems({ listUserMechanisms }, 'mechanisms');
  },
  data() {
    return {
      works: [],
      materials: [],
      mechanisms: [],
      tabs: [
        {
          name: 'Darbi',
          type: 'works',
          data: false,
          query: { listUserWorks },
          extra: ['materials', 'mechanisms'],
          active: true
        },{
          name: 'Materiāli',
          type: 'materials',
          data: false,
          query: { listUserMaterials },
          active: false
        },{
          name: 'Mehānismi',
          type: 'mechanisms',
          data: false,
          query: { listUserMechanisms },
          active: false
        }
      ],
      properties: {
        name: 'Nosaukums',
        id: 'ID',
        createdAt: 'Izveidošanas datums',
        updatedAt: 'Atjaunošanas datums',
        unit_of_measurement: 'Mērvienība',
        global_code: 'Globālais kods',
        manufacturer_code: 'Izstrādātāja kods',
        manufacturer_name: 'Izstrādātājs',
        amount: 'Daudzums',
        price: 'Cena (EUR)',
        code: 'Kods',
        time_norm: 'Laika norma (c/h)',
        pay_rate: 'Darba samaksas likme (EUR/h)',
        salary: 'Darba alga (EUR)',
        sum: 'Summa (EUR)'
      }
    }
  },
  computed: {
    activeTab() {
      return this.tabs.find(x => x.active);
    }
  },
  methods: {
    async listUserItems(query, type) {
      const queryName = Object.keys(query)[0];
      const items = await API.graphql({
        query: query[queryName],
      });
      this[type] = items.data[queryName].items;
      this.tabs.find(x => x.type === type).data = true;
    },
    changeTab(tab) {
      if (!tab.active) {
        this.activeTab.active = false;
        tab.active = true;
        if (!tab.data) this.listUserItems(tab.query, tab.type);
        if (tab.extra) {
          tab.extra.forEach(ex => {
            const extra = this.tabs.find(x => x.type === ex);
            if (!extra.data) this.listUserItems(extra.query, extra.type);
          });
        }
      }
    },
    async graphqlMutation({ items, operation, type }) {
      var singleInput, batchInput;

      if (operation === 'delete') {
        [singleInput, batchInput] = [{ id: items[0] }, { id: items }];
      } else if (operation === 'create' || operation === 'update') {
        [singleInput, batchInput] = [items[0], items];
      } else {
        return;
      }
      
      const operationName = operation.charAt(0).toUpperCase() + operation.slice(1);
      const typeName = type.charAt(0).toUpperCase() + type.slice(1);
      const queryName = items.length > 1 ? 'batch' + operationName + typeName : operation + typeName;
      const typeMap = {
        Work: 'works',
        Material: 'materials',
        Mechanism: 'mechanisms'
      }

      if (items.length > 25) {
        this.splitInChunks(items, 25).forEach(arr => {
          API.graphql({
            query: Mutation[queryName],
            variables: { input: operation === 'delete' ? { id: arr } : arr }
          }).then(response => this.performMutation(response, operation, typeMap[typeName], queryName));
        });
      } else {
        API.graphql({
          query: Mutation[queryName],
          variables: { input: items.length > 1 ? batchInput : singleInput }
        }).then(response => this.performMutation(response, operation, typeMap[typeName], queryName));
      }
    },
    splitInChunks(array, size) {
      const result = [];
      for (let [i, j] = [0, array.length]; i < j; i += size) {
        result.push(array.slice(i, i + size));
      }
      return result;
    },
    performMutation(response, operation, type, query) {
      const replaceOrAdd = item => {
        const index = this[type].findIndex(i => i.id === item.id);
        index !== -1 ? this.$set(this[type], index, item) : this[type].push(item);
      }
      
      const data = response.data[query];
      if (operation === 'delete') {
        /*const parent = this.tabs.find(x => x.extra === type);
        const update = [];
        const deleteParentExtras = item => {
          this[parent.type].forEach(x => {
            if (x[type] && x[type].some(y => y.id === item.id)) {
              const extra = x[type].map(z => z.id).filter(id => id !== item.id);
              update.push({id: x.id, [type]: extra.length > 0 ? extra : null});
            }
          });
        }*/

        if (Array.isArray(data)) {
          for (let item of data) {
            const index = this[type].findIndex(i => i.id === item.sort);
            if (index !== -1) this[type].splice(index, 1);
            //if (parent && parent.data) deleteParentExtras(item);
            //else this.listUserItems(parent.query, parent.type).then(() => deleteParentExtras(item));
          }
        } else {
          this[type].splice(this[type].findIndex(i => i.id === data.id), 1);
          //if (parent && parent.data) deleteParentExtras(data);
          //else this.listUserItems(parent.query, parent.type).then(() => deleteParentExtras(data));
        }

        //if (update.length > 0)
        //	this.graphqlMutation({ items: update, operation: 'update', type: parent.type.slice(0, parent.type.length - 1) });
      } else {
        Array.isArray(data) ? data.forEach(item => replaceOrAdd(item)) : replaceOrAdd(data);
      }

      if (operation === 'update' || operation === 'delete') {
        var parent = { type };
        while (parent) {
          parent = this.tabs.find(x => x.extra?.some(y => y === parent.type));
          if (parent) this.listUserItems(parent.query, parent.type);
        }
      }
    }
  }
};
</script>

<style>
.main td:first-child {
  border: none;
}

.main th:first-child {
  border-color: #afafaf;
  background: transparent;
}

.add-section {
  background: #2c3e50;
  padding: 18px 0;
}

.add-section select, .add-section button, .add-section label {
  padding: 4px;
  margin: 4px;
  font-family: inherit;
}

.add-section input {
  padding: 5px;
  margin: 4px;
  font-family: inherit;
  background: #384c61;
  border: 1px solid #5d758e;
  color: #fff;
}

.add-section input::placeholder {
  color: #91a5b9;
}

.add-section select {
  background: #384c61;
  border: 1px solid #5d758e;
  color: #fff;
}

.add-section label {
  font-size: 14px;
  color: #fff;
}

.add-section > div:nth-child(n+2):not(.error-block)::before {
  content: '';
  color: white;
  display: block;
  width: 50%;
  margin: 10px auto;
  height: 1px;
  background: #506880;
}

.add-group-wrap {
  display: inline-block;
}

button:disabled,
button[disabled] {
  opacity: 0.5;
  cursor: default;
}

input:disabled[type="text"],
input[disabled][type="text"] {
  background: none;
  box-shadow: none;
  border-color: transparent;
}

/*.main td:nth-child(3), td:nth-child(4) {
  padding: 5px;
}*/

.add-menu {
  z-index: 99999;
  position: absolute;
  background: #fff;
  border: 1px solid #afafaf;
  border-radius: 5px;
  box-shadow: 0px 0px 5px rgb(0 0 0 / 0.3);
  font-size: 14px;
  font-weight: bold;
  max-height: 400px;
  min-width: 198px;
  overflow-y: auto;
  text-align: left;
}

.add-menu ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.add-menu li {
  padding: 7px;
  cursor: pointer;
  word-break: break-all;
}

.add-menu li:hover {
  background: #d6ebf3;
}

.add-menu input {
  width: calc(100% - 20px);
  padding: 4px;
  margin: 4px;
}

.add-menu:focus, .add-menu:focus-within {
  display: block !important;
  outline: none;
}

.small-text {
  font-size: 11px;
  font-weight: normal;
}

td input[type="text"]:not(.material-menu input, .mechanism-menu input) {
  text-align: center;
  font-size: inherit;
  max-width: 150px;
  border-radius: 5px;
  border: 1px solid #8c8c8c;
  padding: 3px;
  box-shadow: inset 0px 0px 5px #d7dcda;
}

td input[type="number"] {
  text-align: center;
  font-size: inherit;
  max-width: 75px;
  border-radius: 5px;
  border: 1px solid #8c8c8c;
  padding: 3px;
  box-shadow: inset 0px 0px 5px #d7dcda;
}

input[type="checkbox"] {
  transform: scale(1.2);
}

.dropdown {
  display: inline-block;
  position: relative;
}

.dropdown-data {
  display: none;
  z-index: 999;
  position: absolute;
  background: #fff;
  border-bottom: 1px solid #afafaf;
  border-radius: 0px 0px 5px 5px;
  box-shadow: 0px 0px 5px rgb(0 0 0 / 0.3);
  min-width: 100%;
  max-width: 200px;
  padding: 0;
  margin: 0;
  list-style: none;
}

.dropdown-data a {
  text-decoration: none;
}

.dropdown-data li {
  padding: 7px;
  font-size: 14px;
  font-weight: bold;
  color: #2c3e50;
}

.dropdown-data li:hover {
  background: #d6ebf3;
}

.dropdown > button {
  margin-bottom: 0;
}

.dropdown > button::after {
  content: "▼";
  font-size: 11px;
  padding: 3px;
}

.dropdown > button:focus + .dropdown-data {
  display: block;
}

.dropdown-data:hover {
  display: block;
}

.dropdown-data:focus-within {
  display: block;
}

.tab-bar button {
  border: none;
  background: #fff;
  padding: 7px;
  flex: 1;
}

.tab-bar {
  display: flex;
  align-items: baseline;
  font-size: 14px;
  color: #2c3e50;
}

.tab-bar .active {
  border-bottom: 5px solid #42b983;
  font-weight: bold;
}

.tab-data {
  padding: 7px;
}

.tab-data input {
  margin-bottom: 7px;
  max-width: 186px;
}

.overflow-x-wrapper {
  overflow-x: auto;
  margin: 10px 5px;
}

/*.transform-right {
  right: 0;
  transform: translate(0, 0);
  -webkit-transform: translate(0, 0);
  -ms-transform: translate(0, 0);
}*/

.flip-left {
  transform: translate(-100%, 0px);
}

.tab-bg {
  background: #5d758e;
}

.tab-control {
  display: flex;
}

.tab-control a {
  flex: 1;
  padding: 20px 15px 15px 15px;
  color: #fff;
  text-decoration: none;
  cursor: pointer;
}

.tab-control .active {
  border-top: 5px solid #42b983;
  background: #2c3e50;
  padding: 15px;
}

.tab-control a:not(.active):hover {
  background: #67809a;
}

.search-group-wrap {
  display: inline-block;
}

.sortable {
  cursor: pointer;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

.sortable::after {
  content: "\21C5";
  color: #d0d5da;
  font-weight: normal;
  font-size: 15px;
}

.sorted.asc::after, .sorted.desc::after {
  font-size: 14px;
  color: #fff;
}

.sorted.asc::after {
  content: "▲";
}

.sorted.desc::after {
  content: "▼";
}

.wrapper {
  max-width: 1300px;
  margin: 0 auto;
}

.added-item {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  padding: 5px;
  text-align: left;
}

.added-item::after {
  content: "";
  height: 1px;
  width: 100%;
  background: #dedede;
  position: absolute;
  bottom: 0;
}

.amount {
  color: #7fb5ca;
}

@media screen and (max-width: 400px) {
  .add-menu {
    max-width: 198px;
  }
  .add-group {
    display: flex;
    flex-direction: column;
  }
  .add-group-wrap {
    display: block;
  }
  .add-group input {
    flex: 1;
    margin: 4px 10px;
  }
  .add-group button {
    margin: 4px auto;
  }
  .tab-control {
    flex-direction: column;
  }
  .search-group {
    display: flex;
    flex-direction: column;
  }
  .search-group-wrap {
    display: block;
  }
  .search-group input, .search-group select {
    flex: 1;
    margin: 4px 10px;
  }
  .search-group button {
    margin: 4px auto;
  }
}

@media screen and (max-width: 300px) {
  .add-menu {
    min-width: 115px;
  }
}
</style>
