<template>
  <div class="estimate">
    <div v-for="(group, i) in rowGroups" class="row-group" :key="i">
      <div v-for="(value, key, j) in group" class="row" :key="j">
        <span>{{ value }}</span>
        <span>
          <input :type="key === 'marketYear' || key === 'extraPercent' ? 'number' : 'text'" v-model.trim="input[key]">
        </span>
      </div>
    </div>
    <div class="row-group">
      <div class="row">
        <span>Darbi</span>
        <span>
          <div v-for="item in estimateWorks" style="margin-bottom: 5px;" :key="item.id">
            {{ item.name }}
            <button
            class="btn-round-small btn-red hover-3"
            style="margin-left: 4px;"
            @click="removeWork(item.id)">
              &#x00D7;
            </button>
          </div>
          <div class="work-menu" v-if="availableWorks.length > 0">
            <input type="text" v-model.trim="workSearch" placeholder="Nosaukums..." ref="workSearch">
            <ul>
              <li v-for="item in filtered" @click="addWork(item)" :key="item.id">
                {{ item.name }} <span class="amount">({{ item.amount }})</span>
              </li>
            </ul>
          </div>
        </span>
      </div>
      <div class="row">
        <div class="error-block" v-if="error.display" style="display: block;" @click="hideError()"><span>{{ error.message }}</span></div>
        <button class="btn btn-green border" style="margin-left: auto;" @click="generatePdf">
          Izveidot PDF
        </button>
      </div>
    </div>
  </div>
</template>

<script>
import estimateTemplate from '../jspdf/estimateTemplate';
import { API } from 'aws-amplify';
import { listUserWorks } from "../graphql/queries";

export default {
  created() {
    this.listUserWorks();
  },
  data() {
    return {
      rowGroups: [
        { estimateNumber: 'Tāmes numurs', estimateName: 'Darbu veids vai konstruktīvā elementa nosaukums' },
        {
          buildingName: 'Būves nosaukums',
          objectName: 'Objekta nosaukums',
          objectAddress: 'Objekta adrese',
          orderNumber: 'Pasūtījuma numurs'
        },
        { marketYear: 'Tirgus cenu gads', basedOn: 'Pamatojoties uz' },
        { extraPercent: 'Materiālu, grunts apmaiņas un būvgružu transporta izdevumi (%)' }
      ],
      input: {
        estimateNumber: '',
        estimateName: '',
        buildingName: '',
        objectName: '',
        objectAddress: '',
        orderNumber: '',
        marketYear: new Date().getFullYear(),
        basedOn: '',
        extraPercent: 5
      },
      works: [],
      estimateWorks: [],
      workSearch: '',
      error: {
        message: '',
        display: false
      }
    }
  },
  computed: {
    availableWorks() {
      return this.works.filter(x => !this.estimateWorks.map(y => y.id).includes(x.id));
    },
    filtered() {
      return this.availableWorks.filter(x => x.name.toLowerCase().includes(this.workSearch.toString().toLowerCase()));
    }
  },
  methods: {
    async listUserWorks() {
      const items = await API.graphql({
        query: listUserWorks
      });
      this.works = items.data.listUserWorks.items;

      if (this.$route.query.works) {
        this.estimateWorks = this.works.filter(x => this.$route.query.works.includes(x.id));
      }
    },
    addWork(item) {
      this.estimateWorks.push(item);
      this.workSearch = '';
      this.$refs.workSearch.focus();
    },
    removeWork(id) {
      this.estimateWorks.splice(this.estimateWorks.findIndex(i => i.id === id), 1);
    },
    generatePdf() {
      const { input } = this;

      if (Object.values(input).some(x => x === '' || !x)) {
        this.displayError('Pārliecinieties, lai visi lauki būtu aizpildīti!');
        return;
      } else if (this.estimateWorks.length === 0) {
        this.displayError('Jābūt pievienotam vismaz vienam darbam');
        return;
      }

      this.hideError();

      
      const doc = estimateTemplate(input, this.generateTableBody());
      doc.save(`${input.estimateName.toLowerCase().replaceAll(' ', '_')}.pdf`);
    },
    generateTableBody() {
      const { input } = this;
      const rows = [];

      var workCapacityTotal = 0;
      var salaryTotal = 0;
      var materialsTotal = 0;
      var mechanismsTotal = 0;

      for (let i = 1; i <= this.estimateWorks.length; i++) {
        const item = this.estimateWorks[i - 1];
        const salary = +(Math.ceil(item.time_norm * item.pay_rate + "e+2") + "e-2");
        const workCapacity = +(Math.ceil(item.time_norm * item.amount + "e+2") + "e-2");
        const salarySum = +(Math.ceil(salary * item.amount + "e+2") + "e-2");
        rows.push([`${i}.`, item.code, item.name, item.unit_of_measurement, item.amount, item.time_norm, item.pay_rate.toFixed(2), salary.toFixed(2), null, null, salary.toFixed(2), workCapacity, salarySum.toFixed(2), null, null, salarySum.toFixed(2)]);
        workCapacityTotal += workCapacity;
        salaryTotal += salarySum;

        if (item.materials) {
          for (const material of item.materials) {
            const materialName = material.manufacturer_name ? `${material.manufacturer_name} ${material.name}` : material.name;
            const materialPriceSum = +(Math.ceil(material.price * material.amount + "e+2") + "e-2");
            rows.push([null, null, materialName, material.unit_of_measurement, material.amount, null, null, null, material.price.toFixed(2), null, material.price.toFixed(2), null, null, materialPriceSum.toFixed(2), null, materialPriceSum.toFixed(2)]);
            materialsTotal += materialPriceSum;
          }
        }

        if (item.mechanisms) {
          for (const mechanism of item.mechanisms) {
            const mechanismName = mechanism.manufacturer_name ? `${mechanism.manufacturer_name} ${mechanism.name}` : mechanism.name;
            const mechanismPriceSum = +(Math.ceil(mechanism.price * mechanism.amount + "e+2") + "e-2");
            rows.push([null, null, mechanismName, mechanism.unit_of_measurement, mechanism.amount, null, null, null, null, mechanism.price.toFixed(2), mechanism.price.toFixed(2), null, null, null, mechanismPriceSum.toFixed(2), mechanismPriceSum.toFixed(2)]);
            mechanismsTotal += mechanismPriceSum;
          }
        }
      }

      const extraCosts = +(Math.ceil(materialsTotal / 100 * input.extraPercent + "e+2") + "e-2");
      const subTotal = +(Math.round(salaryTotal + materialsTotal + mechanismsTotal + "e+2") + "e-2");
      const total = +(Math.round(subTotal + extraCosts + "e+2") + "e-2");
      const materialsWithExtra = +(Math.round(materialsTotal + extraCosts + "e+2") + "e-2");
      rows.push([
        { content: 'Kopā:', colSpan: 11, styles: { fontStyle: 'bold', halign: 'right' } },
        { content: workCapacityTotal, styles: { fontStyle: 'bold' } },
        { content: salaryTotal.toFixed(2), styles: { fontStyle: 'bold' } },
        { content: materialsTotal.toFixed(2), styles: { fontStyle: 'bold' } },
        { content: mechanismsTotal.toFixed(2), styles: { fontStyle: 'bold' } },
        { content: subTotal.toFixed(2), styles: { fontStyle: 'bold' } },
      ], [
        { content: `Materiālu, grunts apmaiņas un būvgružu transporta izdevumi ${input.extraPercent || 0}%:`, colSpan: 11, styles: { halign: 'right' } },
        null,
        null,
        extraCosts.toFixed(2),
        null,
        extraCosts.toFixed(2)
      ], [
        { content: 'Tiešās izmaksas kopā:', colSpan: 11, styles: { fontStyle: 'bold', halign: 'right' } },
        null,
        { content: salaryTotal.toFixed(2), styles: { fontStyle: 'bold' } },
        { content: materialsWithExtra.toFixed(2), styles: { fontStyle: 'bold' } },
        { content: mechanismsTotal.toFixed(2), styles: { fontStyle: 'bold' } },
        { content: total.toFixed(2), styles: { fontStyle: 'bold' } },
      ]);

      return rows;
    },
    displayError(message) {
      this.error.message = message;
      this.error.display = true;
    },
    hideError() {
      if (this.error.display) this.error.display = false;
    }
  }
}
</script>

<style scoped>
.estimate {
  max-width: 600px;
  margin: 0 auto;
}

input, label {
  padding: 4px;
  margin: 4px;
}

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

.row {
  display: flex;
  margin: 0 auto;
  position: relative;
  padding: 10px;
  word-break: break-word;
  align-items: center;
}

.row span {
  flex: 1;
}

.row-group:nth-child(n+2)::before {
  content: '';
  color: white;
  display: block;
  width: 100%;
  height: 1px;
  background: #c5c5c5;
}

.row span:first-child:not(.error-block span, .amount):after {
  content: ':';
  float: right;
}

.work-menu {
  z-index: 99999;
  background: #fff;
  border: 1px solid #afafaf;
  border-radius: 5px;
  font-size: 14px;
  font-weight: bold;
  width: fit-content;
  text-align: left;
  margin: 0 auto;
  max-height: 300px;
  overflow: auto;
}

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

.work-menu li {
  padding: 7px;
  cursor: pointer;
}

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

.work-menu > input {
  width: calc(100% - 20px);
}

.error-block {
  flex: 1;
}

.amount {
  color: #7fb5ca;
}

@media screen and (max-width: 400px) {
  .row {
    flex-direction: column;
  }
}
</style>