// 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>
  <a-spin :spinning="loadingData">
    <a-form
            :ref="formRef"
            :model="form"
            :rules="rules"
            layout="vertical"
            class="form"
            v-ctrl-enter="handleSubmit"
            @finish="handleSubmit">
      <div v-if="template && template.userdataid">
        <a-typography-text>
            The template "{{ $t(this.template.name) }}" is linked to Userdata "{{ $t(this.template.userdataname) }}" with override policy "{{ $t(this.template.userdatapolicy) }}"
        </a-typography-text><br/><br/>
        <div v-if="templateUserDataParams.length > 0 && !doUserdataOverride">
          <a-typography-text v-if="this.template && this.template.userdataid && templateUserDataParams.length > 0">
              Enter the values for the variables in userdata
          </a-typography-text>
          <a-input-group>
            <a-table
              size="small"
              style="overflow-y: auto"
              :columns="userDataParamCols"
              :dataSource="templateUserDataParams"
              :pagination="false"
              :rowKey="record => record.key">
              <template #bodyCell="{ column, record }">
                <template v-if="column.key === 'value'">
                  <a-input v-model:value="templateUserDataValues[record.key]" />
                </template>
              </template>
            </a-table>
          </a-input-group>
        </div><br/><br/>
      </div>
      <div v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE' || userdataDefaultOverridePolicy === 'APPEND' || !userdataDefaultOverridePolicy">
        <span v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE'" >
          {{ $t('label.user.data.do.override') }}
          <a-switch v-model:checked="doUserdataOverride" style="margin-left: 10px"/>
        </span>
        <span v-if="userdataDefaultOverridePolicy === 'APPEND'">
          {{ $t('label.user.data.do.append') }}
          <a-switch v-model:checked="doUserdataAppend" style="margin-left: 10px"/>
        </span>
        <a-step>
          <template #description>
            <div v-if="doUserdataOverride || doUserdataAppend || !userdataDefaultOverridePolicy" style="margin-top: 15px">
              <a-card
                :tabList="userdataTabList"
                :activeTabKey="userdataTabKey"
                @tabChange="key => onUserdataTabChange(key, 'userdataTabKey')">
                <div v-if="userdataTabKey === 'userdataregistered'">
                  <a-step
                    v-if="isUserAllowedToListUserDatas">
                    <template #description>
                      <div>
                        <user-data-selection
                          :items="items"
                          :row-count="rowCount.userDatas"
                          :disabled="template.userdatapolicy === 'DENYOVERRIDE'"
                          :loading="loading.userDatas"
                          :preFillContent="dataPreFill"
                          @select-user-data-item="($event) => updateUserData($event)"
                          @handle-search-filter="($event) => handleSearchFilter('userData', $event)"
                        />
                        <div v-if="userDataParams.length > 0">
                          <a-input-group>
                            <a-table
                              size="small"
                              style="overflow-y: auto"
                              :columns="userDataParamCols"
                              :dataSource="userDataParams"
                              :pagination="false"
                              :rowKey="record => record.key">
                              <template #bodyCell="{ column, record }">
                                <template v-if="column.key === 'value'">
                                  <a-input v-model:value="userDataValues[record.key]" />
                                </template>
                              </template>
                            </a-table>
                          </a-input-group>
                        </div>
                      </div>
                    </template>
                  </a-step>
                </div>
                <div v-else>
                  <a-form-item name="userdata" ref="userdata" >
                    <a-textarea
                      placeholder="Userdata"
                      v-model:value="form.userdata">
                    </a-textarea>
                  </a-form-item>
                </div>
              </a-card>
            </div>
          </template>
        </a-step>
      </div>
      <div :span="24" class="action-button">
        <a-button @click="closeAction">{{ $t('label.cancel') }}</a-button>
        <a-button :loading="loadingData" ref="submit" type="primary" @click="handleSubmit">{{ $t('label.ok') }}</a-button>
      </div>
    </a-form>
  </a-spin>
</template>

<script>
import { ref, reactive, toRaw } from 'vue'
import { getAPI, postAPI } from '@/api'
import { genericCompare } from '@/utils/sort.js'
import UserDataSelection from '@views/compute/wizard/UserDataSelection'

export default {
  name: 'ResetUserData',
  components: {
    UserDataSelection
  },
  props: {
    resource: {
      type: Object,
      required: true
    },
    preFillContent: {
      type: Object,
      default: () => {}
    }
  },
  data () {
    return {
      items: [],
      total: 0,
      columns: [
        {
          dataIndex: 'name',
          title: this.$t('label.name'),
          sorter: (a, b) => genericCompare(a?.name || '', b?.name || ''),
          width: '40%'
        },
        {
          dataIndex: 'account',
          title: this.$t('account'),
          width: '30%'
        },
        {
          dataIndex: 'domain',
          title: this.$t('domain'),
          width: '30%'
        }
      ],
      selectedRowKeys: [],
      options: {
        page: 1,
        pageSize: 10,
        listall: false,
        response: 'json'
      },
      filter: '',
      rowCount: {},
      loading: {
        userDatas: false
      },
      loadingData: false,
      doUserdataOverride: false,
      doUserdataAppend: false,
      userdataTabList: [],
      userdataDefaultOverridePolicy: 'ALLOWOVERRIDE',
      userData: {},
      userDataParams: [],
      userDataParamCols: [
        {
          title: this.$t('label.key'),
          dataIndex: 'key'
        },
        {
          title: this.$t('label.value'),
          dataIndex: 'value',
          key: 'value'
        }
      ],
      userDataValues: {},
      templateUserDataCols: [
        {
          title: this.$t('label.user.data'),
          dataIndex: 'userdata'
        },
        {
          title: this.$t('label.user.data.policy'),
          dataIndex: 'userdataoverridepolicy'
        }
      ],
      templateUserDataParams: [],
      templateUserDataValues: {},
      template: {},
      userdataTabKey: 'userdataregistered',
      dataPreFill: {},
      userdata: {}
    }
  },
  created () {
    this.initForm()
    this.fetchData()
    this.loadUserdataTabList()
    this.fetchTemplateData()
    this.dataPreFill = this.preFillContent && Object.keys(this.preFillContent).length > 0 ? this.preFillContent : {}
  },
  methods: {
    initForm () {
      this.formRef = ref()
      this.form = reactive({})
      this.rules = reactive({})
    },
    fetchData () {
      this.loadingData = true
      this.items = []
      this.total = 0
      getAPI('listUserData', this.options).then(response => {
        this.total = response.listuserdataresponse.count
        if (this.total !== 0) {
          this.items = response.listuserdataresponse.userdata
        }
      }).finally(() => {
        this.loadingData = false
      })
    },
    fetchTemplateData () {
      const params = {}
      params.id = this.resource.templateid
      params.isrecursive = true
      params.templatefilter = 'all'
      params.isready = true
      var apiName = 'listTemplates'
      getAPI(apiName, params).then(json => {
        const templateResponses = json.listtemplatesresponse.template
        this.template = templateResponses[0]
        this.updateTemplateLinkedUserData(this.template.userdataid)
        this.userdataDefaultOverridePolicy = this.template.userdatapolicy
      })
    },
    updateTemplateLinkedUserData (id) {
      if (id === '0') {
        return
      }
      this.templateUserDataParams = []

      getAPI('listUserData', { id: id }).then(json => {
        const resp = json?.listuserdataresponse?.userdata || []
        if (resp) {
          var params = resp[0].params
          if (params) {
            var dataParams = params.split(',')
          }
          var that = this
          that.templateUserDataParams = []
          if (dataParams) {
            dataParams.forEach(function (val, index) {
              that.templateUserDataParams.push({
                id: index,
                key: val
              })
            })
          }
        }
      })
    },
    loadUserdataTabList () {
      this.userdataTabList = [{
        key: 'userdataregistered',
        tab: this.$t('label.user.data.registered')
      },
      {
        key: 'userdatatext',
        tab: this.$t('label.user.data.text')
      }]
    },
    onUserdataTabChange (key, type) {
      this[type] = key
      this.userDataParams = []
    },
    isUserAllowedToListUserDatas () {
      return Boolean('listUserData' in this.$store.getters.apis)
    },
    updateUserData (id) {
      if (id === '0') {
        this.form.userdataid = undefined
        return
      }
      this.form.userdataid = id
      this.userDataParams = []
      getAPI('listUserData', { id: id }).then(json => {
        const resp = json?.listuserdataresponse?.userdata || []
        if (resp.length > 0) {
          var params = resp[0].params
          if (params) {
            var dataParams = params.split(',')
          }
          var that = this
          dataParams.forEach(function (val, index) {
            that.userDataParams.push({
              id: index,
              key: val
            })
          })
        }
      })
    },
    onSelectChange (selectedRowKeys) {
      this.selectedRowKeys = selectedRowKeys
    },
    handleSearch (keyword) {
      this.filter = keyword
      this.options.keyword = keyword
      this.fetchData()
    },
    handleTableChange (pagination) {
      this.options.page = pagination.current
      this.options.pageSize = pagination.pageSize
      this.fetchData()
    },
    handleSubmit () {
      if (this.loadingData) return
      const values = toRaw(this.form)
      this.loadingData = true
      console.log(values)
      const params = {
      }
      if (values.userdata && values.userdata.length > 0) {
        params.userdata = this.$toBase64AndURIEncoded(values.userdata)
      }
      if (values.userdataid) {
        params.userdataid = values.userdataid
      }
      var idx = 0
      if (this.templateUserDataValues) {
        for (const [key, value] of Object.entries(this.templateUserDataValues)) {
          params['userdatadetails[' + idx + '].' + `${key}`] = value
          idx++
        }
      }
      if (this.userDataValues) {
        for (const [key, value] of Object.entries(this.userDataValues)) {
          params['userdatadetails[' + idx + '].' + `${key}`] = value
          idx++
        }
      }
      params.id = this.resource.resetUserDataResourceId ? this.resource.resetUserDataResourceId : this.resource.id

      const resetUserDataApiName = this.resource.resetUserDataApiName ? this.resource.resetUserDataApiName : 'resetUserDataForVirtualMachine'

      postAPI(resetUserDataApiName, params).then(json => {
        this.$message.success({
          content: `${this.$t('label.action.user.data.reset')} - ${this.$t('label.success')}`,
          duration: 2
        })
        this.$emit('refresh-data')
        this.closeAction()
      }).catch(error => {
        this.$notifyError(error)
      }).finally(() => {
        this.loadingData = false
      })
    },
    closeAction () {
      this.$emit('close-action')
    }
  }
}
</script>

<style scoped lang="scss">
.form {
  width: 90vw;
  @media (min-width: 800px) {
    width: 45vw;
  }
}
</style>
