// 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>
    <a-card class="breadcrumb-card">
      <a-row>
        <a-col :span="14" style="padding-left: 6px">
          <breadcrumb :resource="resource">
            <template #end>
              <a-button
                style="margin-top: 4px"
                :loading="loading"
                shape="round"
                size="small"
                @click="fetchData()">
                <template #icon><ReloadOutlined /></template>
                {{ $t('label.refresh') }}
              </a-button>
            </template>
          </breadcrumb>
        </a-col>
        <a-col :span="10">
          <span style="float: right">
            <action-button
              :style="dataView ? { float: device === 'mobile' ? 'left' : 'right' } : { 'margin-right': '10px', display: 'inline-flex' }"
              :loading="loading"
              :actions="actions"
              :selectedRowKeys="selectedRowKeys"
              :dataView="dataView"
              :resource="resource"
              @exec-action="execAction"/>
          </span>
        </a-col>
      </a-row>
    </a-card>

    <div class="row-element">
      <resource-view
        v-if="dataView"
        :resource="resource"
        :loading="loading"
        :tabs="$route.meta.tabs" />
      <tree-view
        v-else
        :key="treeViewKey"
        :treeData="treeData"
        :treeSelected="treeSelected"
        :treeStore="domainStore"
        :loading="loading"
        :tabs="$route.meta.tabs"
        :treeDeletedKey="treeDeletedKey"
        @change-resource="changeResource"
        @change-tree-store="changeDomainStore"/>
    </div>

    <div v-if="showAction">
      <domain-action-form
        :showAction="showAction"
        :resource="resource"
        :action="action"/>
    </div>
    <domain-delete-confirm
    v-if="showDeleteConfirm"
    :domain="deleteDomainResource"
    @close="showDeleteConfirm = false"
    @confirm="confirmDeleteDomain" />
  </div>
</template>

<script>
import { getAPI, callAPI } from '@/api'
import store from '@/store'
import { mixinDevice } from '@/utils/mixin.js'

import Breadcrumb from '@/components/widgets/Breadcrumb'
import ActionButton from '@/components/view/ActionButton'
import TreeView from '@/components/view/TreeView'
import DomainActionForm from '@/views/iam/DomainActionForm'
import ResourceView from '@/components/view/ResourceView'
import DomainDeleteConfirm from '@/components/view/DomainDeleteConfirm'
import eventBus from '@/config/eventBus'

export default {
  name: 'DomainView',
  components: {
    Breadcrumb,
    ActionButton,
    TreeView,
    DomainActionForm,
    ResourceView,
    DomainDeleteConfirm
  },
  mixins: [mixinDevice],
  data () {
    return {
      resource: {},
      loading: false,
      selectedRowKeys: [],
      treeViewKey: 0,
      treeData: [],
      treeSelected: {},
      showAction: false,
      action: {},
      dataView: false,
      domainStore: {},
      treeDeletedKey: null,
      showDeleteConfirm: false,
      deleteDomainResource: null
    }
  },
  computed: {
    actions () {
      let actions = []
      if (this.$route && this.$route.meta) {
        if (this.$route.meta.actions) {
          actions = this.$route.meta.actions
        }
      }
      return actions
    }
  },
  beforeRouteUpdate (to, from, next) {
    next()
  },
  beforeRouteLeave (to, from, next) {
    this.changeDomainStore({})
    next()
  },
  created () {
    this.domainStore = store.getters.domainStore
    this.fetchData()
    eventBus.on('refresh-domain-icon', () => {
      if (this.$showIcon()) {
        this.fetchData()
      }
    })
  },
  watch: {
    '$route' (to, from) {
      // When the route changes from /domain/:id to /domain or vice versa, the component is not destroyed and created again
    // So, we need to watch the route params to fetch the data again to update the component
      if (to.path.startsWith('/domain') && from.params.id !== to.params.id) {
        this.fetchData()
      }
    }
  },
  provide () {
    return {
      parentCloseAction: this.closeAction,
      parentFetchData: this.fetchData,
      parentForceRerender: this.forceRerender
    }
  },
  methods: {
    fetchData () {
      this.treeData = []
      this.treeSelected = {}
      const params = { listall: true }
      if (this.$route && this.$route.params && this.$route.params.id) {
        this.resource = {}
        this.dataView = true
        params.id = this.$route.params.id
      } else {
        this.dataView = false
        params.id = this.$store.getters.userInfo.domainid
      }

      this.loading = true
      params.showicon = true
      getAPI('listDomains', params).then(json => {
        const domains = json.listdomainsresponse.domain || []
        this.treeData = this.generateTreeData(domains)
        this.resource = domains[0] || {}
        this.treeSelected = domains[0] || {}
      }).catch(error => {
        if ([401].includes(error.response.status)) {
          return
        }

        this.$notification.error({
          message: this.$t('message.request.failed'),
          description: error.response.headers['x-description'],
          duration: 0
        })

        if ([405].includes(error.response.status)) {
          this.$router.push({ path: '/exception/403' })
        }

        if ([430, 431, 432].includes(error.response.status)) {
          this.$router.push({ path: '/exception/404' })
        }

        if ([530, 531, 532, 533, 534, 535, 536, 537].includes(error.response.status)) {
          this.$router.push({ path: '/exception/500' })
        }
      }).finally(f => {
        this.loading = false
      })
    },
    execAction (action) {
      if (action.api === 'deleteDomain') {
        this.deleteDomainResource = this.resource
        this.showDeleteConfirm = true
        return
      }
      this.treeDeletedKey = null
      this.actionData = []
      this.action = action
      this.action.params = store.getters.apis[this.action.api].params
      const paramFields = this.action.params
      paramFields.sort(function (a, b) {
        if (a.name === 'name' && b.name !== 'name') { return -1 }
        if (a.name !== 'name' && b.name === 'name') { return -1 }
        if (a.name === 'id') { return -1 }
        if (a.name < b.name) { return -1 }
        if (a.name > b.name) { return 1 }
        return 0
      })
      this.action.paramFields = []
      if (action.args) {
        var args = action.args
        if (typeof action.args === 'function') {
          args = action.args(action.resource, this.$store.getters)
        }
        if (args.length > 0) {
          this.action.paramFields = args.map(function (arg) {
            return paramFields.filter(function (param) {
              return param.name.toLowerCase() === arg.toLowerCase()
            })[0]
          })
        }
      }
      this.showAction = true
      for (const param of this.action.paramFields) {
        if (param.type === 'list' && ['tags', 'hosttags'].includes(param.name)) {
          param.type = 'string'
        }
        if (param.type === 'uuid' || param.type === 'list' || param.name === 'account' || (this.action.mapping && param.name in this.action.mapping)) {
          this.listUuidOpts(param)
        }
      }
      this.action.loading = false
    },
    listUuidOpts (param) {
      if (this.action.mapping && param.name in this.action.mapping && !this.action.mapping[param.name].api) {
        return
      }
      const paramName = param.name
      const possibleName = 'list' + paramName.replace('ids', '').replace('id', '').toLowerCase() + 's'
      let params = { listall: true }
      let possibleApi
      if (this.action.mapping && param.name in this.action.mapping && this.action.mapping[param.name].api) {
        possibleApi = this.action.mapping[param.name].api
        if (this.action.mapping[param.name].params) {
          const customParams = this.action.mapping[param.name].params(this.resource)
          if (customParams) {
            params = { ...params, ...customParams }
          }
        }
      } else if (paramName === 'id') {
        possibleApi = this.apiName
      } else {
        for (const api in store.getters.apis) {
          if (api.toLowerCase().startsWith(possibleName)) {
            possibleApi = api
            break
          }
        }
      }
      if (!possibleApi) {
        return
      }
      param.loading = true
      param.opts = []
      callAPI(possibleApi, params)
        .then(json => {
          param.loading = false
          const responseObj = Object.values(json).find(obj => obj.includes('response'))
          if (responseObj) {
            const responseData = Object.entries(responseObj).find(([res, value]) => res !== 'count')
            if (responseData) {
              param.opts = responseData[1]
            }
          }
        })
        .catch(() => {
          param.loading = false
        })
    },
    generateTreeData (treeData) {
      const result = []
      const rootItem = treeData

      rootItem[0].title = rootItem[0].title ? rootItem[0].title : rootItem[0].name
      rootItem[0].key = rootItem[0].id ? rootItem[0].id : 0
      rootItem[0].resourceIcon = rootItem[0].icon || {}
      delete rootItem[0].icon

      if (!rootItem[0].haschild) {
        rootItem[0].isLeaf = true
      }

      result.push(rootItem[0])
      return result
    },
    changeResource (resource) {
      this.treeSelected = resource
      this.resource = this.treeSelected
    },
    changeDomainStore (domainStore) {
      this.domainStore = domainStore
      store.dispatch('SetDomainStore', domainStore)
    },
    closeAction () {
      this.showAction = false
    },
    confirmDeleteDomain () {
      const domain = this.deleteDomainResource
      const params = { id: domain.id, cleanup: true }

      callAPI('deleteDomain', params).then(json => {
        const jobId = json.deletedomainresponse.jobid

        this.$pollJob({
          jobId,
          title: this.$t('label.action.delete.domain'),
          description: domain.name,
          loadingMessage: `${this.$t('label.action.delete.domain')} ${domain.name}`,
          successMessage: `${this.$t('label.action.delete.domain')} ${domain.name}`,
          catchMessage: this.$t('error.fetching.async.job.result'),
          successMethod: () => {
            this.$router.replace({ path: '/domain' })
            this.resource = {}
            this.treeSelected = {}
            this.treeDeletedKey = null
            this.treeViewKey += 1
            this.$nextTick(() => {
              this.fetchData()
            })
          }
        })
      }).catch(error => {
        this.$notification.error({
          message: this.$t('message.request.failed'),
          description: error.response?.headers['x-description'] || this.$t('message.request.failed')
        })
      }).finally(() => {
        this.showDeleteConfirm = false
        this.deleteDomainResource = null
        this.treeDeletedKey = null
      })
    },
    forceRerender () {
      this.treeViewKey += 1
    }
  }
}
</script>

<style scoped lang="less">
  .breadcrumb-card {
    margin-left: -24px;
    margin-right: -24px;
    margin-top: -16px;
    margin-bottom: 12px;
  }

  .row-element {
    margin-top: 10px;
    margin-bottom: 10px;
  }

  .ant-breadcrumb {
    vertical-align: text-bottom;
  }

  .ant-breadcrumb .anticon {
    margin-left: 8px;
  }
</style>
