<!--
      Licensed to the Apache Software Foundation (ASF) under one or more
      contributor license agreements. See the NOTICE file distributed with
      this work for additional information regarding copyright ownership.
      The ASF licenses this file to You under the Apache License, Version
      2.0 (the "License"); you may not use this file except in compliance
      with the License. You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0 Unless required by
      applicable law or agreed to in writing, software distributed under the
      License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
      CONDITIONS OF ANY KIND, either express or implied. See the License for
      the specific language governing permissions and limitations under the
      License.
  -->
<template>
  <div class="page-content">

    <h1>Employee-Details ({{employeeId}})</h1>

    <e-record styleClass="formPanel" :record="employeeRecord">
      <table class="inputForm" style="width:400px">
        <colgroup>
          <col width="120px"/>
          <col/>
        </colgroup>
        <tr><e-control column="salutation" /></tr>
        <tr><e-control column="firstName" /></tr>
        <tr><e-control column="lastName" /></tr>
        <tr><e-control column="dateOfBirth" format="[yyyy-MM-dd]"/></tr>
        <tr><e-control column="departmentId" /></tr>
        <tr><e-control column="gender"   /> </tr>
        <tr><e-control column="phoneNumber" /></tr>
        <tr><e-control column="email" /></tr>
        <tr><e-control column="salary" /></tr>
        <tr><e-control column="retired" /></tr>
      </table>
    </e-record>

    <div class="buttonBar">
      <button @click="doReturnToList($event)">Back</button>
      <button @click="doDelete($event)" v-if="allowDelete">Delete</button>
      <button @click="doSave($event)">Save</button>
    </div>

  </div>
</template>

<script>
  import EMPAPI from '../api/emp-api'
  import eRecord from '../components/e-record.vue'
  import eControl from '../components/e-control.vue'

  export default {
    name: 'employeeDetail',

    components: {
      eRecord,
      eControl
    },

    props: {
      employeeId: {
        required: true
      }
    },

    data () {
      return {
        employeeRecord: undefined
      }
    },

    computed: {
      allowDelete: function () {
        return (this.employeeRecord && !this.employeeRecord.data._newRecord)
      }
    },

    created: function (empid) {
      EMPAPI.assertLoggedIn(this)
      if (this.employeeId === 0) {
        this.addNew()
      } else {
        this.loadDetails()
      }
    },

    methods: {
      addNew: function () {
        EMPAPI.debug('create employee record')
        EMPAPI.createEmployeeRecord(this.employeeId)
          .done(response => (this.onLoadDone(response)))
          .fail(response => (this.$parent.handleError(response, '/employeeList')))
      },
      loadDetails: function () {
        EMPAPI.debug('load employee record')
        EMPAPI.readEmployeeRecord(this.employeeId)
          .done(response => (this.onLoadDone(response)))
          .fail(response => (this.$parent.handleError(response, '/employeeList')))
      },
      doSave: function (event) {
        this.$parent.clearMessages()
        EMPAPI.debug('load employee record')
        EMPAPI.updateEmployee(this.employeeRecord.data)
          .done(response => (this.onUpdateDone(response)))
          .fail(response => (this.$parent.handleError(response)))
      },
      doDelete: function (event) {
        if (!confirm('Do you really want to delete this employee?')) {
          return
        }
        this.$parent.clearMessages()
        EMPAPI.debug('load employee record')
        EMPAPI.deleteEmployee(this.employeeId)
          .done(response => (this.onUpdateDone(response)))
          .fail(response => (this.$parent.handleError(response, '/employeeList')))
      },
      doReturnToList: function (event) {
        this.$router.push('/employeeList')
      },
      onLoadDone (result) {
        this.employeeRecord = result
      },
      onUpdateDone (result) {
        EMPAPI.debug('employee record successfully updated')
        this.$router.push('/employeeList')
      }
    }
  }
</script>
