/* eslint-disable camelcase */
<template>
  <div class="invoice">
    <div class="header-container">
      <h3 v-if="currentStatus === 'pending'" class="title">
        Purchase Order (Pending Approval)
      </h3>
      <h3 v-else-if="currentStatus === 'approve'" class="title" >
        Purchase Order (Approved)
      </h3>
      <h3 v-else-if="currentStatus === 'request_change'" class="title">
        Purchase Order (Please Change)
        <div class="error">
          {{ statuses[statuses.length - 1].comment }}
        </div>
      </h3>
      <h3 v-else class="title">
        Purchase Order
      </h3>
    </div>

    <div class="invoice-container">
      <form @submit.prevent="submitForm">
        <div class="buyer-detail card">
          <div class="card-body">
            <div class="card-title">
              <h5>
                My Infomation
              </h5>
            </div>
            <div class="form-group">
              <label for="marking">Marking</label>
              <input id="marking" v-model="$v.form.formData.marking.$model" type="text" class="form-control" disabled>
            </div>
            <div class="form-group">
              <label for="buyer-company">Buyer's Company</label>
              <input id="buyer-company"
                     v-model="$v.form.formData.buyer_company.$model"
                     :class="{
                       'is-invalid': $v.form.formData.buyer_company.$invalid && $v.form.formData.buyer_company.$dirty,
                       'is-valid': !$v.form.formData.buyer_company.$invalid && $v.form.formData.buyer_company.$dirty
                     }"
                     :disabled="!editable"
                     type="text"
                     class="form-control"
                     @blur="$v.form.formData.buyer_company.$touch()">
              <div class="invalid-feedback">
                Buyer Company Required
              </div>
            </div>
            <!-- <div class="form-group">
              <label for="gst-id">GST ID</label>
              <input id="gst-id" type="text" class="form-control" disabled>
            </div> -->
            <div class="form-group">
              <label for="contact-number">Contact Number</label>
              <input id="contact-number"
                     v-model.trim="$v.form.formData.contact_no.$model"
                     :class="{
                       'is-invalid': $v.form.formData.contact_no.$invalid && $v.form.formData.contact_no.$dirty,
                       'is-valid': !$v.form.formData.contact_no.$invalid && $v.form.formData.contact_no.$dirty
                     }"
                     :disabled="!editable"
                     type="tel"
                     class="form-control"
                     @blur="$v.form.formData.contact_no.$touch()">
              <div class="invalid-feedback">
                Contact Number Required
              </div>
            </div>
            <div class="form-group">
              <label for="reg-no">Company Registration Number</label>
              <input id="reg-no"
                     v-model.trim="$v.form.formData.reg_no.$model"
                     :class="{
                       'is-invalid': $v.form.formData.reg_no.$invalid && $v.form.formData.reg_no.$dirty,
                       'is-valid': !$v.form.formData.reg_no.$invalid && $v.form.formData.reg_no.$dirty
                     }"
                     :disabled="!editable"
                     type="text" class="form-control"
                     @blur="$v.form.formData.reg_no.$touch()">
              <div class="invalid-feedback">
                Company Registration Number Required
              </div>
            </div>
            <div class="form-group">
              <label for="address">Address</label>
              <textarea id="address"
                        v-model="$v.form.formData.address.$model"
                        :class="{
                          'is-invalid': $v.form.formData.address.$invalid && $v.form.formData.address.$dirty,
                          'is-valid': !$v.form.formData.address.$invalid && $v.form.formData.address.$dirty
                        }"
                        :disabled="!editable"
                        class="form-control"
                        cols="30"
                        rows="4"
                        @blur="$v.form.formData.address.$touch()"/>
              <div class="invalid-feedback">
                Address Required
              </div>
            </div>
          </div>
        </div>
        <div class="conversion-rate">
          <h5>
            Conversion: {{ rate }}
          </h5>
        </div>
        <div class="billing-detail-title">
          <h5>Billing Detail</h5>
        </div>
        <div class="billing-detail-lines">
          <table class="table">
            <thead>
              <tr>
                <th class="align-middle">#</th>
                <th class="align-middle">Stock Code</th>
                <th class="align-middle">Description</th>
                <th class="text-center align-middle">Qty</th>
                <th class="text-center align-middle">Unit Price (RMB)</th>
                <th class="text-center align-middle">Unit Price (RM)</th>
                <th class="text-center align-middle">Total Amount (RM)</th>
                <th>&nbsp;</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>&nbsp;</td>
                <td>
                  <div class="form-group">
                    <input v-model="$v.form.addLine.stock_code.$model"
                           :class="{
                             'is-invalid': $v.form.addLine.stock_code.$invalid && $v.form.addLine.stock_code.$dirty,
                             'is-valid': !$v.form.addLine.stock_code.$invalid && $v.form.addLine.stock_code.$dirty
                           }"
                           :disabled="!editable"
                           name="stockcode" type="text"
                           class="form-control"
                           @blur="$v.form.addLine.stock_code.$touch()">
                    <div class="invalid-feedback">
                      Stock Code Required
                    </div>
                  </div>
                </td>
                <td>
                  <div class="form-group">
                    <textarea id="description"
                              v-model="$v.form.addLine.description.$model"
                              :class="{
                                'is-invalid': $v.form.addLine.description.$invalid && $v.form.addLine.description.$dirty,
                                'is-valid': !$v.form.addLine.description.$invalid && $v.form.addLine.description.$dirty
                              }"
                              :disabled="!editable"
                              name="description" cols="20" rows="2"
                              @blur="$v.form.addLine.description.$touch()"/>
                    <div class="invalid-feedback">
                      Maximum length for description is 256 characters
                    </div>
                  </div>
                </td>
                <td>
                  <div class="form-group">
                    <input id="quantity"
                           v-model="$v.form.addLine.quantity.$model"
                           :class="{
                             'is-invalid': $v.form.addLine.quantity.$invalid && $v.form.addLine.quantity.$dirty,
                             'is-valid': !$v.form.addLine.quantity.$invalid && $v.form.addLine.quantity.$dirty
                           }"
                           :disabled="!editable"
                           type="number"
                           min="1"
                           class="form-control"
                           name="quantity"
                           @change="onUnitPriceRM()"
                           @blur="$v.form.addLine.quantity.$touch()">
                    <div class="invalid-feedback">
                      Quantity Required
                    </div>
                  </div>
                </td>
                <td>
                  <div class="form-group">
                    <input id="rmb-unit-price"
                           v-model="$v.form.addLine.unit_price_rmb.$model"
                           :class="{
                             'is-invalid': $v.form.addLine.unit_price_rmb.$invalid && $v.form.addLine.unit_price_rmb.$dirty,
                             'is-valid': !$v.form.addLine.unit_price_rmb.$invalid && $v.form.addLine.unit_price_rmb.$dirty
                           }"
                           :disabled="!editable"
                           type="number"
                           min="0"
                           name="rmb-unit-price"
                           class="form-control"
                           @change="onUnitPriceRMB()"
                           @blur="$v.form.addLine.unit_price_rmb.$touch()">
                    <div class="invalid-feedback">
                      Unit Price Required
                    </div>
                  </div>
                </td>
                <td>
                  <div class="form-group">
                    <input id="rm-unit-price"
                           v-model="$v.form.addLine.unit_price_rm.$model"
                           :class="{
                             'is-invalid': $v.form.addLine.unit_price_rm.$invalid && $v.form.addLine.unit_price_rm.$dirty,
                             'is-valid': !$v.form.addLine.unit_price_rm.$invalid && $v.form.addLine.unit_price_rm.$dirty
                           }"
                           :disabled="!editable"
                           type="number"
                           min="0"
                           name="rm-unit-price"
                           class="form-control"
                           @change="onUnitPriceRM()"
                           @blur="$v.form.addLine.unit_price_rm.$touch()">
                    <div class="invalid-feedback">
                      Unit Price Required
                    </div>
                  </div>
                </td>
                <td>
                  <div class="form-group">
                    <input id="total"
                           v-model="$v.form.addLine.total.$model"
                           type="number"
                           min="0"
                           name="subtotal"
                           class="form-control"
                           disabled>
                  </div>
                </td>
                <td>
                  <button :disabled="!editable" class="btn btn-success" type="button" @click="onAddLine()">
                    Add
                  </button>
                </td>
              </tr>
              <tr v-for="(line, index) in form.formData.lines" :key="index">
                <td class="line-number text-center align-middle">
                  {{ index + 1 }}
                </td>
                <td class="stock-code text-center align-middle">
                  {{ line.stock_code }}
                </td>
                <td class="description align-middle">
                  {{ line.description }}
                </td>
                <td class="quantity text-center align-middle">
                  {{ line.quantity }}
                </td>
                <td class="unit-price-rmb text-center align-middle">
                  {{ line.unit_price_rmb }}
                </td>
                <td class="unit-price-rm text-center align-middle">
                  {{ line.unit_price_rm }}
                </td>
                <td class="line-subtotal text-center align-middle">
                  {{ line.total }}
                </td>
                <td>
                  <button :disabled="!editable" type="button" class="btn btn-danger" @click="onRemoveLine(index)">
                    Remove
                  </button>
                </td>
              </tr>
            </tbody>
            <tfoot>
              <tr class="subtotal-line">
                <td colspan="5"/>
                <td class="subtotal-title text-center">
                  Subtotal
                </td>
                <td class="subtotal text-center">
                  {{ subtotal }}
                </td>
                <td>
                  &nbsp;
                </td>
              </tr>
              <tr class="subtotal-line">
                <td colspan="5"/>
                <td class="subtotal-title text-center">
                  Adjustment
                </td>
                <td class="subtotal text-center">
                  {{ form.formData.adjustment || 'auto' }}
                </td>
                <td>
                  &nbsp;
                </td>
              </tr>
              <tr class="service-charge">
                <td colspan="5"/>
                <td class="subtotal-title text-center">
                  Billing Charge
                </td>
                <td class="subtotal text-center">
                  {{ billing_charge }}
                </td>
                <td>
                  &nbsp;
                </td>
              </tr>
              <tr v-if="tax > 0" class="gst-line">
                <td colspan="5"/>
                <td class="gst-title text-center">
                  GST
                </td>
                <td class="gst-total text-center">
                  {{ tax }}
                </td>
                <td>
                  &nbsp;
                </td>
              </tr>
              <tr class="total-line">
                <td colspan="5"/>
                <td class="total-title text-center">
                  Total
                </td>
                <td class="total text-center">
                  {{ total }}
                </td>
                <td>
                  &nbsp;
                </td>
              </tr>
              <tr>
                <td colspan="5">&nbsp;</td>
                <td colspan="2">
                  <button :disabled="!editable" class="btn btn-success btn-block" type="submit">
                    Create PO
                  </button>
                </td>
              </tr>
            </tfoot>
          </table>
        </div>
      </form>
    </div> <!-- invoice-container -->
    <div v-if="role === 'admin'" class="admin-panel">
      <div v-if="statuses.length > 0" class="comments">
        <h5>Log</h5>
        <table class="table comment-table">
          <thead>
            <tr>
              <th>Date Time</th>
              <th>Status</th>
              <th>Comment</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(comment, index) in statuses" :key="index">
              <td>{{ comment.created_at }}</td>
              <td>{{ comment.status }}</td>
              <td>{{ comment.comment }}</td>
            </tr>
          </tbody>
        </table>
      </div>
      <br>
      <form @submit.prevent="onSubmitStatus">
        <h5>Admin Panel</h5>
        <div class="form-group">
          <label for="action">Action</label>
          <select id="action"
                  v-model="$v.form.postStatus.status.$model"
                  :class="{
                    'is-invalid': $v.form.postStatus.status.$invalid && $v.form.postStatus.status.$dirty,
                    'is-valid': !$v.form.postStatus.status.$invalid && $v.form.postStatus.status.$dirty
                  }"
                  name="action"
                  class="form-control">
            <option value="approve">Approve</option>
            <option value="request_change">Request Change</option>
          </select>
          <div class="invalid-feedback">
            Action Required
          </div>
        </div>
        <div class="form-group">
          <label for="comment">Comment</label>
          <textarea id="comment"
                    v-model="$v.form.postStatus.comment.$model"
                    :class="{
                      'is-invalid': $v.form.postStatus.comment.$invalid && $v.form.postStatus.comment.$dirty,
                      'is-valid': !$v.form.postStatus.comment.$invalid && $v.form.postStatus.comment.$dirty
                    }"
                    name="comment"
                    cols="30" rows="3" class="form-control" />
          <div class="invalid-feedback">
            Comment required if you are requesting change from customer.
          </div>
        </div>
        <button type="submit" class="btn btn-success">Submit</button>
      </form>
    </div>
  </div>
</template>
<style>
  input {
    min-width: 6em;
  }
  .container {
    margin-left: 10% !important;
    margin-right: 10% !important;
  }
  .el-main {
    padding-left: 0 !important;
    padding-right: 0 !important;
  }
  .title {
    margin-top: 1em;
    padding-left: 1.7em;
    padding-bottom: 0 !important;
  }
  .buyer-detail {
    grid-area: buyer-detail;
    width: 100%;
    margin-bottom: 3em;
  }
  .card-body {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: wrap !important;
    justify-content: space-around !important;
  }
  .buyer-detail .form-group {
    width: 45%;
  }
  .card-title {
    width: 100%;
  }
  .conversion-rate {
    grid-area: conversion-rate;
  }
  .conversion-rate h5 {
    float: right;
    background-color: lightblue;
    padding-left: 1em;
    padding-right: 1em;
  }
  .billing-detail-title {
    width: 100%;
    grid-area: billing-detail-title;
  }
  .billing-detail-lines {
    width: 100%;
    grid-area: billing-detail-lines;
  }
  .invoice-container  {
    padding: 2em 3em;
    display: grid;
    grid-template-areas:
    'buyer-detail buyer-detail'
    'billing-detail-title conversion-rate'
    'billing-detail-lines billing-detail-lines';
  }
  .header-container {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
  }
  .admin-panel {
    margin-left: 3em;
    margin-right: 3em;
  }
  .error {
    color: red;
  }
</style>

<script>
import Vue from 'vue'
import Vuelidate from 'vuelidate'
import { required, numeric, decimal, requiredIf, maxLength } from 'vuelidate/lib/validators'
import axios from 'axios'
Vue.use(Vuelidate)

export default {
  name: 'NewComponent',
  props: {
    trackerConfig: {
      type: Object,
      default: function () {
        return {
          status: 5,
          term: null
        }
      }
    },
    booking_id: {
      type: String,
      default: null
    },
    booking_details: {
      type: Object,
      default: function () {
        return {
          id: null,
          bia: null,
          amount: null,
          user_bankslip_path: null,
          china_bankslip_path: null,
          marking: null,
          billing_charge: null
        }
      }
    }
  },
  data: function () {
    return {
      form: {
        formData: {
          buyer_company: '',
          address: '',
          contact_no: '',
          marking: this.booking_details.marking,
          gst_id: '',
          reg_no: '',
          adjustment: '',
          lines: []
        },
        addLine: {
          order: null,
          description: null,
          quantity: null,
          unit_price_rmb: null,
          unit_price_rm: null,
          stock_code: null,
          total: null
        },
        postStatus: {
          status: null,
          comment: null
        }
      },
      rate: 0,
      billing_charge: 0,
      amount: 0,
      bia: 0,
      invoice_total: 0,
      tax: 0,
      billing_fee: 0,
      subtotal: 0,
      total: 0,
      role: null,
      currentStatus: null,
      statuses: []
    }
  },
  computed: {
    editable: function () {
      // Not editable if created and not admin
      return this.role === 'admin' || this.currentStatus === null || this.currentStatus === 'request_change'
    }
  },
  validations: {
    form: {
      formData: {
        buyer_company: {
          required
        },
        address: {
          required
        },
        contact_no: {
          required
        },
        marking: {
          required
        },
        reg_no: {
          required
        },
        gst_id: {

        },
        adjustment: {
        }
      },
      addLine: {
        stock_code: {
          required
        },
        description: {
          maxLength: maxLength(256)
        },
        quantity: {
          required,
          numeric
        },
        unit_price_rmb: {
          required,
          decimal
        },
        unit_price_rm: {
          required,
          decimal
        },
        total: {
          required,
          decimal
        }
      },
      postStatus: {
        status: {
          required
        },
        comment: {
          required: requiredIf(function () {
            return this.form.postStatus.status === 'request_change'
          })
        }
      }
    }
  },
  watch: {
    booking_details: function () {
      const {
        marking,
        tax,
        bia,
        amount,
        rate,
        billing_charge
      } = this.booking_details

      this.form.formData.marking = marking
      this.tax = tax
      this.amount = amount
      this.bia = bia
      this.rate = rate
      this.billing_charge = billing_charge
      this.total = this.billing_charge // Will not work if there is tax. Temporary fix.
    }
  },
  mounted () {
    this.getInvoice()
    this.getUser()
  },
  methods: {
    onAddLine: function () {
      if (this.$v.form.addLine.$invalid) {
        this.$v.form.addLine.$touch()
        return
      }
      const {
        order,
        description,
        quantity,
        stock_code,
        unit_price_rmb,
        unit_price_rm,
        total
      } = this.form.addLine
      const data = {
        order: order,
        description,
        quantity,
        stock_code,
        unit_price_rmb,
        unit_price_rm,
        total
      }
      
      this.form.formData.lines.push(data)
      this.setTotal()
      this.clearAddLine()
    },
    onUnitPriceRMB: function () {
      if (!this.form.addLine.unit_price_rmb) {
        return
      }
      this.form.addLine.unit_price_rm = (+this.form.addLine.unit_price_rmb / +this.rate).toFixed(2)
      this.form.addLine.total = (+this.form.addLine.unit_price_rm * +this.form.addLine.quantity).toFixed(2)
    },
    onUnitPriceRM: function () {
      if (!this.form.addLine.unit_price_rm) {
        return
      }
      this.form.addLine.unit_price_rmb = (this.form.addLine.unit_price_rm * this.rate).toFixed(2)
      this.form.addLine.total = (+this.form.addLine.unit_price_rm * +this.form.addLine.quantity).toFixed(2)
    },
    onRemoveLine: function (line) {
      this.form.formData.lines.splice(line, 1)
      this.setTotal()
    },
    setTotal: function () {
      if (this.form.formData.lines.length < 1) {
        this.subtotal = 0
        this.form.formData.adjustment = 0
        this.total = this.billing_charge // Temporary fix. Will return error if GST is implemented.
        return
      }

      this.subtotal = parseFloat(this.form.formData.lines.map(line => line.total).reduce((a, b) => parseFloat(a) + parseFloat(b))).toFixed(2)

      // Set Adjustment if CNY total is equal to Invoice CNY Total
      const cnyTotal = this.form.formData.lines.map(l => +l.unit_price_rmb * +l.quantity).reduce((a, b) => a + b)
      if (cnyTotal === this.amount) {
        this.form.formData.adjustment = parseFloat(+this.bia - +this.subtotal - this.billing_charge).toFixed(2)
      } else {
        this.form.formData.adjustment = 0
      }
      this.total = parseFloat(+this.subtotal + (+this.subtotal * (+this.tax || 0) / 100) + +this.billing_charge + +this.form.formData.adjustment).toFixed(2)
    },
    clearAddLine: function () {
      this.form.addLine.order = null
      this.form.addLine.description = null
      this.form.addLine.quantity = null
      this.form.addLine.unit_price_rmb = null
      this.form.addLine.unit_price_rm = null
      this.form.addLine.stock_code = null
      this.form.addLine.total = null
      this.$v.form.addLine.$reset()
    },
    submitForm () {
      if (this.$v.form.formData.$invalid) {
        this.$v.form.formData.$touch()
        console.log('form not valid')
        return
      }

      if (this.bia != this.total) {
        console.log('amount not matched')
        alert(`PO Total RM${this.total} Does Not Match Expected RM${this.bia}`)
        return
      }

      // create order in line
      this.form.formData.lines
        .forEach((el, i) => {
          this.form.formData.lines[i].order = (i + 1)
        })

      if (this.currentStatus) {
        console.log('edit invoice')
        this.editInvoice()
      } else {
        console.log('create invoice')
        this.createInvoice()
      }
    },
    createInvoice () {
      const url = '/api/invoice/' + this.booking_id
      axios
        .post(url, this.form.formData)
        .then(resp => {
          alert('PO Created. Pending Approval.')
          this.$router.push({ name: 'home' })
        })
        .catch(err => {
          alert(JSON.stringify(err.response.data.message))
          console.error(err.response.data.message)
        })
    },
    editInvoice () {
      const url = '/api/invoice/' + this.booking_id
      axios
        .put(url, this.form.formData)
        .then(resp => {
          alert(`PO have been edited${this.role === 'admin' ? ' by admin.' : '. Pending Approval'}`)
          this.$router.push({ name: 'home' })
        })
        .catch(err => {
          alert(JSON.stringify(err.response.data.message))
          console.error(err.response.data.message)
        })
    },
    getInvoice () {
      const url = '/api/invoice/' + this.booking_id
      axios
        .get(url)
        .then(resp => {
          this.form.formData.buyer_company = resp.data.buyer_company
          this.form.formData.contact_no = resp.data.contact_no
          this.form.formData.address = resp.data.address
          this.form.formData.reg_no = resp.data.reg_no

          this.form.formData.lines = []
          this.statuses = []

          resp.data.lines.forEach((el, i) => {
            this.form.formData.lines.push(el)
          })

          resp.data.status.forEach((el, i) => {
            this.statuses.push(el)
          })

          this.currentStatus = resp.data.status[resp.data.status.length - 1].status

          this.form.formData.adjustment = resp.data.adjustment

          this.setTotal()
        })
    },
    getUser () {
      const url = '/api/user'
      axios
        .get(url)
        .then(resp => {
          this.role = resp.data.role
        })
    },
    onSubmitStatus () {
      if (this.$v.form.postStatus.$invalid) {
        this.$v.form.postStatus.$touch()
        return
      }
      const url = '/api/invoice/' + this.booking_id + '/comment'
      axios
        .post(url, this.form.postStatus)
        .then(resp => {
          this.getInvoice()
          this.form.postStatus.status = null
          this.form.postStatus.comment = null
          this.$v.form.postStatus.$reset()
          alert('Status Updated')
        })
    }
  }
}
</script>
