// 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">
            <span slot="end">
              <template slot="title">
                {{ $t('label.refresh') }}
              </template>
              <a-button
                style="margin-top: 4px"
                :loading="loading"
                shape="round"
                size="small"
                icon="reload"
                @click="fetchData()">
                {{ $t('label.refresh') }}
              </a-button>
            </span>
          </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
        :treeData="treeData"
        :treeSelected="treeSelected"
        :treeStore="domainStore"
        :loading="loading"
        :tabs="$route.meta.tabs"
        @change-resource="changeResource"
        @change-tree-store="changeDomainStore"
        :actionData="actionData"/>
    </div>

    <div v-if="showAction">
      <domain-action-form
        :showAction="showAction"
        :resource="resource"
        :action="action"/>
    </div>
  </div>
</template>

<script>
import { api } 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'

export default {
  name: 'DomainView',
  components: {
    Breadcrumb,
    ActionButton,
    TreeView,
    DomainActionForm,
    ResourceView
  },
  mixins: [mixinDevice],
  data () {
    return {
      resource: {},
      loading: false,
      selectedRowKeys: [],
      treeData: [],
      actionData: [],
      treeSelected: {},
      showAction: false,
      action: {},
      dataView: false,
      domainStore: {}
    }
  },
  computed: {
    actions () {
      let actions = []
      if (this.$route && this.$route.meta) {
        if (this.$route.meta.actions) {
          actions = this.$route.meta.actions
        }
      }
      return actions
    }
  },
  beforeCreate () {
    this.form = this.$form.createForm(this)
  },
  beforeRouteUpdate (to, from, next) {
    next()
  },
  beforeRouteLeave (to, from, next) {
    this.changeDomainStore({})
    next()
  },
  created () {
    this.domainStore = store.getters.domainStore
    this.fetchData()
  },
  watch: {
    '$route' (to, from) {
      if (to.fullPath !== from.fullPath && !to.fullPath.includes('action/')) {
        this.fetchData()
      }
    },
    '$i18n.locale' (to, from) {
      if (to !== from) {
        this.fetchData()
      }
    }
  },
  provide () {
    return {
      parentCloseAction: this.closeAction,
      parentUpdActionData: this.updateActionData,
      parentFetchData: this.fetchData
    }
  },
  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

      api('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) {
      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 = []
      api(possibleApi, params).then(json => {
        param.loading = false
        for (const obj in json) {
          if (obj.includes('response')) {
            for (const res in json[obj]) {
              if (res === 'count') {
                continue
              }
              param.opts = json[obj][res]
              this.$forceUpdate()
              break
            }
            break
          }
        }
      }).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

      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
    },
    updateActionData (data) {
      this.actionData.push(data)
    }
  }
}
</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>
