<i18n>
{
  "en": {
    "inputCredentials": "Login credentials",
    "backendName": "Backend name",
    "backendEmptyError": "This field can not be empty.",
    "backendType": "Backend type",
    "backendtypeEmptyError": "Please choose a backend type.",
    "stepperOptional": "optional",
    "pending": "pending",
    "progress": "in progress ...",
    "success": "success",
    "error": "error",
    "testConnection": "Test connection"
  },
  "de": {
    "inputCredentials": "Anmeldedaten",
    "backendName": "Backend Name",
    "backendEmptyError": "Dieses Feld darf nicht leer sein.",
    "backendType": "Backend Typ",
    "backendtypeEmptyError": "Bitte wähle einen Backendtyp aus.",
    "stepperOptional": "Optional",
    "pending": "nicht getestet",
    "progress": "test läuft ...",
    "success": "erfolgreich",
    "error": "Fehler",
    "testConnection": "Verbindung überprüfen"
  }
}
</i18n>
<template>
  <v-dialog
    :value="$store.state.backends.edit"
    @input="$store.commit('backends/setEdit', $event)"
    max-width="500px"
    scrollable
  >
    <!-- dialog needs scrollable attribute-->
    <v-card>
      <v-card-title style="padding: 0px">
        <v-stepper v-model="step" horizontal style="width: 100%; background: transparent;" class="elevation-3">
          <v-stepper-header>
            <v-stepper-step
              :complete="stepCompleted >= 1"
              step="1"
              :editable="stepCompleted >= 1 && !loadData"
              :rules="[() => true]"
            >{{ $t('backendType') }}<small>{{ backendType }}</small>
            </v-stepper-step>
            <v-divider></v-divider>
            <v-stepper-step
              :complete="stepCompleted >= 2"
              step="2"
              :editable="stepCompleted >= 2"
            >{{ $t('inputCredentials') }}</v-stepper-step>
            <v-divider></v-divider>
            <v-stepper-step
              :complete="stepCompleted >= 3"
              step="3"
              :editable="stepCompleted >= 3"
            >{{ $t('testConnection') }}<small>{{ $t('stepperOptional') }}</small>
            </v-stepper-step>
          </v-stepper-header>
        </v-stepper>
      </v-card-title>
      <v-card-text style="height: 500px;">
        <v-form class="edit-backend-form" ref="form" v-model="valid" @submit.prevent="submit" lazy-validation>
          <v-stepper v-model="step" horizontal style="width: 100%; background: transparent" class="elevation-0">
            <v-stepper-items>
              <v-stepper-content step="1">
                <v-select
                  offset-y
                  v-model="backendType"
                  :items="backendChoices"
                  :label="$t('backendType')"
                  :rules="[() => !!backendType || $t('backendtypeEmptyError')]"
                  prepend-icon="view_list"
                ></v-select>
              </v-stepper-content>
              <v-stepper-content step="2">
                <v-text-field
                  v-model="backendName"
                  :label="$t('backendName')"
                  :rules="[() => !!backendName || $t('backendEmptyError')]"
                  ref="backendName"
                  prepend-icon="assignment_ind"
                ></v-text-field>
                <backend-module-edit-dynamic-fields :elements="elements"/>
              </v-stepper-content>
              <v-stepper-content step="3">
                <v-container>
                <v-layout align-center justify-center column>
                <v-btn
                  fab
                  dark
                  icon
                  :loading="loading"
                  :disabled="loading"
                  @click.stop="checkConnection"
                  large
                >
                  <v-icon x-large color="primary">cached</v-icon>
                </v-btn>
                  <div class="display-1">{{ $t('Status') }}: <strong :class="statusColor">{{ statusLabel }}</strong></div>
                </v-layout>
                </v-container>
              </v-stepper-content>
            </v-stepper-items>
          </v-stepper>
        </v-form>
      </v-card-text>
      <v-divider></v-divider>
      <v-card-actions>
        <v-flex xl10 offset-xl2 lg12 text-xs-right>
          <v-btn flat @click.native="$store.commit('backends/setEdit', false)">{{ $t('cancel') }}</v-btn>
          <v-btn color="primary" v-show="step == 1" @click.native="completeStepOne()">{{ $t('continue') }}</v-btn>
          <v-btn color="primary" v-show="step == 2" @click.native="completeStepTwo()">{{ $t('continue') }}</v-btn>
          <v-btn type="submit" @click="submit" v-show="step == 3" class="primary" raised>{{ $t('submit') }}</v-btn>
        </v-flex>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>

<script>
import BackendModuleEditDynamicFields from '@/components/BackendModuleEditDynamicFields'

export default {
  name: 'BackendModuleEdit',
  props: ['backendId'],
  components: {
    BackendModuleEditDynamicFields
  },
  data () {
    return {
      valid: true,
      step: 1,
      stepCompleted: 0,
      backendChoices: [],
      backendType: '',
      backendName: '',
      elements: [],
      loadData: false,
      loading: false,
      statusColor: 'primary--text',
      statusLabel: this.$t('pending')
    }
  },
  methods: {
    submit (event) {
      if (this.$refs.form.validate()) {
        this.$http.post('/api/backends/save', {
          id: this.backendId,
          name: this.backendName,
          type: this.backendType,
          credentials: this.credentials
        }).then(response => {
          // TODO: Add backend saved successfull msg.
          console.log('TODO: Implement snackbar and print backend added successfully msg.')
          this.$store.dispatch('backends/loadData')
          this.$store.commit('backends/setEdit', false)
        }).catch(error => {
          console.log(error)
          // if (error.response.data.status === '') {
          // }
          // this.$refs.form.validate()
        })
      }
    },
    loadBackendTypes () {
      this.$http('/api/backends/getTypes').then(response => {
        this.backendChoices = response.data
      })
    },
    loadInputFields () {
      if (!this.loadData) {
        this.$http('/api/backends/getCredentialsByType?type=' + this.backendType).then(response => {
          this.elements = response.data
        })
      }
    },
    loadBackend (backendId) {
      this.$http('/api/backends/getInfoById?id=' + this.backendId).then(response => {
        this.backendName = response.data.backendName
        this.loadData = true
        this.backendType = response.data.backendType
        const credentialValues = JSON.parse(response.data.backendCredentials)
        this.$http('/api/backends/getCredentialsByType?type=' + this.backendType).then(res => {
          var credentials = res.data

          // Make an array merge to combine the credentials with the values.
          // var mergedCredentials = credentials.map(x => Object.assign(x, credentialValues.find(y => y.id === x.id)))
          var mergedCredentials = mergeObjects(credentials, credentialValues)
          this.elements = mergedCredentials
        })
      })
    },
    completeStepOne () {
      // Error handling
      if (this.backendType !== '') {
        this.loadInputFields()
        this.step = 2
        this.stepCompleted = Math.max(1, this.stepCompleted)
      } else {
        this.$refs.form.validate()
      }
    },
    completeStepTwo () {
      // Error handling
      if (this.backendName !== '') {
        this.step = 3
        this.stepCompleted = Math.max(2, this.stepCompleted)
      } else {
        this.$refs.form.validate()
      }
    },
    checkConnection () {
      // Start the loading animation and reset the label colors.
      this.loading = true
      this.statusColor = 'primary--text'
      this.statusLabel = this.$t('progress')

      // Test the credential connection.
      this.$http.post('/api/backends/checkConnection', {
        name: this.backendName,
        type: this.backendType,
        credentials: JSON.stringify(this.credentials),
        headers: {
          'Cache-Control': 'no-cache'
        }
      }).then(response => {
        if (response.data.success) {
          this.statusColor = 'success--text'
          this.statusLabel = this.$t('success')
        } else {
          this.statusColor = 'error--text'
          this.statusLabel = this.$t('error')
          this.$store.commit('newSnackbar', response.data.error)
        }
        // Set item.loading = false to end the loading animation.
        this.loading = false
      })
    }
  },
  computed: {
    credentials: function () {
      return filterData(this.elements)
    },
    edit: function () {
      return this.$store.state.backends.edit
    }
  },
  watch: {
    edit: function (value) {
      if (value) {
        this.loadBackendTypes()
        this.statusColor = 'primary--text'
        this.statusLabel = this.$t('pending')
        this.$refs.form.reset()
        if (this.backendId !== 0) {
          this.loadBackend(this.backendId)
          this.step = 2
          this.stepCompleted = 3
        } else {
          this.backendName = ''
          this.backendType = ''
          this.step = 1
          this.stepCompleted = 0
          this.elements = []
          this.loadData = false
        }
      }
    }
  }
}

function filterData (obj) {
  var result = []
  obj.forEach(function (element) {
    const e = { id: element.id, value: element.value }
    if (element.elements) {
      e.elements = filterData(element.elements)
    }
    result.push(e)
  })
  return result
}

function mergeObjects (obj1, obj2) {
  var tmp = []
  var merged = obj1.map(x => Object.assign(x, obj2.find(y => {
    if (y.id === x.id) {
      if (x.elements && y.elements) {
        var tmp2 = { id: x.id, elements: mergeObjects(x.elements, y.elements) }
        tmp.push(tmp2)
      }
    }
    return y.id === x.id
  })))

  // Is there a cleaner way?
  tmp.forEach(function (e) {
    merged.forEach(function (r) {
      if (e.id === r.id) {
        r.elements = e.elements
      }
    })
  })
  return merged
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
